2011-08-17 18 views
5

リモートサービスからサムネイル画像やその他のリソースを簡単にダウンロードしているアプリがあります。タイムアウトパラメータが設定されていても、HttpClientが長時間停止する

私はDefaultHttpClientの1つのインスタンスと、私が書いたカスタムクラスを使用して、すべてのダウンロードをスケジュールしています。すべてのダウンロードは、AsyncTask経由でバックグラウンドスレッドでシリアルに実行されます。私はonPostExecuteがAsyncTaskで実行されるまで私のダウンロードルーチンを再実行しません。

これはしばしば完全に機能します。私が20枚の画像を並べると、私のスケジューラーはそのことをうまくやっています。しかし、私は、クライアントがDefaultHttpClientのインスタンスであるclient.executeを呼び出す時点でプロシージャが停止するケースにぶつかります。私は、アプリの周りをナビゲートし、ランダムな操作(リストをスクロールしたり、アクティビティ間を前後にナビゲートするなど)を行うことで、わかりやすく蘇生することができます。 私がやっていることは、ストールしているかデッドロックしているスレッドに "起床"メッセージを送信しているかのようです。

私は、この手順に外部の何かがデッドロック状態のいくつかの種類を引き起こしているかどうかを確認するために自分のアプリケーションのすべての可動部品でログの不快な量を追加しました。私は、失業や再開の時点で何か他のことがプロセスで起こっているかどうかを確認するためにLogCatをpidで表示しています。これに関する最も奇妙な部分は、私は何度も正確な条件を繰り返すことができるということです。

FWIW、HttpClientインスタンスとexecuteメソッドに渡すHttpGetインスタンスの両方でソケットタイムアウトと接続タイムアウトを設定しました。これにより、executeメソッドが早期に返されたり、例外などがスローされたりすることはありません。プロシージャが "キックバック"すると、HttpClient.executeから有効なHttpResponseが返され、すべて正常に動作します。

私はデバッグして、これがどこに上がっているのかを知るためのアイデアはありますか?これは非常に特殊な条件だと認識していますが、は、一般的にAndroidのDefaultHttpClientまたはhttpトラフィックを具体的にデバッグするための高度な方法はありますか?

ありがとうございました!

答えて

5

スレッド間で同じHttpClientを共有していますか?デフォルトではスレッドセーフではありませんので、チェックしてみてください。ほとんどの場合、I/O上でブロックされる可能性があるので、ワイヤデバッグを行うべきです。このようなものを使用すると、HttpClientワイヤダンプログを有効にできます。

Logger.getLogger("org.apache.http.wire").setLevel(Level.FINEST); 
Logger.getLogger("org.apache.http.headers").setLevel(FINEST); 
Logger.getLogger("httpclient.wire.header").setLevel(FINEST); 
Logger.getLogger("httpclient.wire.content").setLevel(FINEST); 

System.setProperty("org.apache.commons.logging.Log", 
    "org.apache.commons.logging.impl.SimpleLog"); 
System.setProperty("org.apache.commons.logging.simplelog.showdatetime", "true"); 
System.setProperty("org.apache.commons.logging.simplelog.log.httpclient.wire", "debug"); 
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http", "debug"); 
System.setProperty("org.apache.commons.logging.simplelog.log.org.apache.http.headers", "debug"); 

有効にするには、次のシェルコマンドを実行します。ワイヤーログはlogcatに出力されます:

+0

応答してくれてありがとう...そのような、そして長続きしない質問への回答を得るのは難しい。私はロギングを試してみるつもりですが、とにかく正しい方向に私を指摘したと思います。私はスレッドプールからスレッドを与えるAsyncTaskを使用しています...これはいくつかの問題を引き起こす可能性があります。私は1つのスレッド派生クラスを試してみますので、diffスレッドで同時にHttpClient.executeを呼び出すことはありません。私はループを再実行する前に実行が戻っても、次のスレッドが入る前に実行が完了していないクリーンアップがある可能性があります。 – Rich

+0

Btw、このコードを追加しましたが表示されませんLogCatの追加ログ。これ以上何かありますか?ログをファイルにダンプしているのですか、それともLogCatで見るべきですか? – Rich

+0

ログインする必要があります。静的なイニシャライザのように、あなたのアプリケーションのコードの前にこれを必ず実行してください。 –

-2

私は前に同様の問題がありました。 HTTPをキューに入れようとすると、httpClient.execute(get);メソッドはデッドロックのように応答を返しません。

HttpResponse response = httpClient.execute(get); 
HttpEntity entity = response.getEntity(); 

これは私のコードです。これはentity.consumeContent();となります。

+0

本当に質問に答えなかった。 –

関連する問題