Edited at

HttpClientをtargetSdkVersion=28でも使う

More than 1 year has passed since last update.


今さら 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 ファイルで次のコンパイル時の依存関係を宣言する必要があります。



build.gradle

android {

useLibrary 'org.apache.http.legacy'
}

ということで、Android 6.0(API Level 23) 以降でも build.gradleuseLibrary '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(起動しない)

でした。


AndroidManifest.xml に uses-library を追記する

burton999 さんのアドバイスを受けて


AndroidManifest.xml

    <application>

<uses-library android:name="org.apache.http.legacy" android:required="false" />


のように記述してみたところ、HttpClient + targetSdkVersion=28 + Android 9 の組み合わせでも一応問題なく起動しました。

本当はさっさと OkHttp3 で全面的に書き直すべきなんでしょうけど、既存のコードが多すぎて作業できずにいるのでもう少しだけこの方法で延命したいと思います。


ついでに

Android 9 からは平文の通信がデフォルトで禁止になるので

java.io.IOException: Cleartext traffic not permitted: http://mixi.jp

のような例外を見かけたりしますがその際は Android 8: Cleartext HTTP traffic not permitted - Stack Overflow あたりを参考にしてください。


リンク