Help us understand the problem. What is going on with this article?

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 あたりを参考にしてください。

リンク

takke
Android用TwitterクライアントのTwitPaneなどを開発しています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away