今さら HttpClient を使ってる人なんていないよねー
2018年にもなって平成だって終わろうとしてるのに、未だに HttpClient
(Apache HttpClient
, DefaultHttpClient
, AndroidHttpClient
) を使ってる人なんていないと思います。
が、私が 2011 年から開発している とあるアプリ ではまだまだ HttpClient
を使っていて、クッキーの処理などでかなりごにょごにょした部分もあり、すぐには移行できない状況でした。
とはいえ、ご存じの通り Playストアの仕様が変わり、2018年8月から新規アプリ、同11月からは既存アプリの更新時にも、targetSdkVersion
を API Level 26(Android 8.0)以上にする必要がでてきました。で、サクッと targetSdkVersion=28
(Android 9) にしてみると ClassNotFoundException
が出て起動すら出来なくなってマジで詰み気味だったので色々試してみました。
結論から言えば AndroidManifest.xml
に少し記述すると起動できました。
以下、少し詳しく書いておきます。
Apache HTTP Client は Android 6.0 で削除されました
Android 6.0 の変更点 | Android Developers によると
Android 6.0 リリースでは、Apache HTTP クライアントのサポートが削除されました。アプリでこのクライアントを使用していて、Android 2.3(API レベル 9)以上を対象としている場合は、代わりに HttpURLConnection クラスを使用してください。この API は透過的データ圧縮と応答のキャッシュによってネットワーク使用を軽減し、電源の消費を最小化するため、効率性が向上します。Apache HTTP API を引き続き使用するには、まず
build.gradle
ファイルで次のコンパイル時の依存関係を宣言する必要があります。
android {
useLibrary 'org.apache.http.legacy'
}
ということで、Android 6.0(API Level 23) 以降でも build.gradle
に useLibrary 'org.apache.http.legacy'
を記述することで利用できていました。
targetSdkVersion=28
+ Android 9 で動作しなくなった
useLibrary 'org.apache.http.legacy'
を記述していても、targetSdkVersion=28
にすると下記の例外が出て Android 9 でアプリが起動すらしなくなりました(Android 8.1 で動くかは試していませんが動いたところで)。
java.lang.NoClassDefFoundError: Failed resolution of: Lorg/apache/http/conn/scheme/SchemeRegistry;
少し試してみたところ、
Android 9 + HttpClient + targetSdkVersion=16 => OK(起動する)
Android 9 + HttpClient + targetSdkVersion=23 => OK(起動する)
Android 9 + HttpClient + targetSdkVersion=24 => OK(起動する)
Android 9 + HttpClient + targetSdkVersion=25 => OK(起動する)
Android 9 + HttpClient + targetSdkVersion=26 => OK(起動する)
Android 9 + HttpClient + targetSdkVersion=27 => OK(起動する)
Android 9 + HttpClient + targetSdkVersion=28 => NG(起動しない)
でした。
targetSdkVersion を上げると Android 9 で DefaultHttpClient で通信ができなくなる(useLibrary 'org.apache.http.legacy' を書いていても) のを確認するために targetSdkVersion を少しずつ上げて試している
— 竹内裕昭 (@takke) 2018年9月21日
targetSdkVersion = 23, 24, 25, 26, 27 は OK、28 にすると Didn't find class "org.apache.http.conn.scheme.SchemeRegistry" で落ちる
— 竹内裕昭 (@takke) 2018年9月21日
AndroidManifest.xml に uses-library を追記する
AndroidManifest.xmlに <uses-library android:name="org.apache.http.legacy" android:required="false”/> を追加でいけたはずです
— burton999@アプリ開発 (@ComicCafeApp) 2018年9月3日
burton999 さんのアドバイスを受けて
<application>
<uses-library android:name="org.apache.http.legacy" android:required="false" />
のように記述してみたところ、HttpClient
+ targetSdkVersion=28
+ Android 9
の組み合わせでも一応問題なく起動しました。
本当はさっさと OkHttp3
で全面的に書き直すべきなんでしょうけど、既存のコードが多すぎて作業できずにいるのでもう少しだけこの方法で延命したいと思います。
targetSdkVersion=28 にしても Manifest に <uses-library android:name="org.apache.http.legacy" android:required="false" /> を書くと動作した。もう少しだけ延命できそう。。
— 竹内裕昭 (@takke) 2018年9月21日
ついでに
Android 9 からは平文の通信がデフォルトで禁止になるので
java.io.IOException: Cleartext traffic not permitted: http://mixi.jp
のような例外を見かけたりしますがその際は Android 8: Cleartext HTTP traffic not permitted - Stack Overflow あたりを参考にしてください。