AndroidHttpClient

今まで{@Hide}※されていたAndroidHttpClientクラス(android.net.http.AndroidHttpClient)だが、Froyoからはその禁が解かれた。
このクラス、Android向けに最適化されているとのことなので使ってみようと思ったのだが、いざDefaultHttpClientから切替えようとするとすんなりいかなかったりする。

  • 型の互換性

コメントに"Subclass of the Apache {@link DefaultHttpClient}"とあるが、AndroidHttpClientクラスはDefaultHttpClientから派生したクラスではない。

    • AndroidHttpClient.java
public final class AndroidHttpClient implements HttpClient

このようにHttpClientを実装しているクラスであり、DefaultHttpClientのサブクラスではないのである。なのに何故「Subclass of」と書かれているか謎だが、ソースを追うと内部ではHttpClientインタフェースのメソッドの殆どをDefaultHttpClientクラスのインスタンスに委譲しており、この点が"サブクラス"と称している理由かもしれない。

なので、HttpClientインタフェースではなく、DefaultHttpClientクラス又はその抽象クラスであるAbstractHttpClientを型に持つクラスを代替えすることはできない。(せめてAbstractHttpClientの実装クラスだったらよかったんだが)

  • 実装の違い

AndroidHttpClientはDefaultHttpClientに比べてよりAndroidに最適化されているという話だが、ソースコードをぱっと見て解る相違点としては

・UIスレッドでの処理を禁止する処理が組み込まれている
Cookieの処理が省かれている
・コンテンツのgzip圧縮処理が追加されている
・SSLSessionCache機能が追加されたSSLSocketFactory(SSLCertificateSocketFactory)が使用されている
・接続タイムアウトが最適化(Connection 20秒、SoTimeout 20秒)されている
・ソケットバッファが最適化(8192Byte)されている
・リダイレクトが禁止されている

これらの違いがあるようだ。

  • 生成方法

Froyoで{@hide}が外れたものの、まだ実装を変える可能性があるのか、コメントには"Don't create this directly, use the {@link #newInstance} factory method."とあるので、インスタンスの生成にコンストラクタは使えない。他のバージョンでは相変わらず"隠されたクラス"な訳で、(Antでビルドすることを前提にできない場合)コード上で使い分けるには、

HttpClient client;
try {
    Class clazz = 
        (Class)Class.forName("android.net.http.AndroidHttpClient");
    Method m = clazz.getMethod("newInstance", new Class{String.class});
    client = (HttpClient)m.invoke(null, new Object{"Android"});        
} catch (Exception e) {
    client = new DefaultHttpClient();        
}

等とリフレクションやファクトリで生成コードを書かなくてはならない。

以上を検討した場合、私の環境ではAndroidHttpClientを使うのは微妙であり、それならば違いを分析してDefaultHttpClientの設定を上書きしたほうが良さげだ。

※{@hide}で注釈されているクラスは{隠し属性}とされ、エクスポートの対象から外されてandroid.jarにも含まれない。