私のAndroidアプリでは、クラウドから画像をダウンロードします。ダウンロードはスレッドで実行され、同じスレッドで、新しくダウンロードした画像を使用して画像ビューも設定します。画像を設定した後、を呼び出しますpostinvalidate()
。
ただし、画像はすぐには表示されません。再描画をすぐに実行する方法はありますか?描画サイクルをトリガーする方法が必要です。
私のAndroidアプリでは、クラウドから画像をダウンロードします。ダウンロードはスレッドで実行され、同じスレッドで、新しくダウンロードした画像を使用して画像ビューも設定します。画像を設定した後、を呼び出しますpostinvalidate()
。
ただし、画像はすぐには表示されません。再描画をすぐに実行する方法はありますか?描画サイクルをトリガーする方法が必要です。
Viewクラスから派生した各クラスには、invalidate()
とpostInvalidate()
メソッドがあります。呼び出されるとinvalidate()
、現在のビューが変更されたため、できるだけ早く再描画する必要があることをシステムに通知します。このメソッドはUIThreadからのみ呼び出すことができるため、UIThreadを使用しておらず、ビューが変更されたことをシステムに通知する場合は、別のメソッドが必要です。このメソッドは非UIThreadからシステムに通知し、ビューはUIThreadの次のイベントループでできるだけ早く再描画されます。postInvalidate()
あなたの場合、AsyncTask
(インテリジェントなバックラウンドスレッド)の助けを借りてあなたが望むことを達成することができます。AsyncTaskはUIスレッドの適切で簡単な使用を可能にします。このクラスを使用すると、スレッドやハンドラーを操作しなくても、UIスレッドでバックグラウンド操作(この場合はバックグラウンドで画像をダウンロード)を実行し、結果を公開(ビットマップをImageViewに設定)できます。
非同期タスクは、バックグラウンドスレッドで実行され、その結果がUIスレッドで公開される計算によって定義されます。非同期タスクは、Params、Progress、Resultと呼ばれる3つの汎用タイプと、begin、doInBackground、processProgress、endと呼ばれる4つのステップによって定義されます。
4つのステップ
非同期タスクが実行されると、タスクは次の4つのステップを実行します。
onPreExecute()
、タスクが実行された直後にUIスレッドで呼び出されます。この手順は通常、タスクを設定するために使用されます。たとえば、クラウドから画像をダウンロードする前にユーザーインターフェースに進行状況バーを表示することで、優れたユーザーエクスペリエンスを提供します。
doInBackground(Params...)
、onPreExecute()の実行が終了した直後にバックグラウンドスレッドで呼び出されます。このステップは、時間がかかる可能性のあるバックグラウンド計算を実行するために使用されます。非同期タスクのパラメーターは、このステップに渡されます。計算の結果はこのステップで返される必要があり、最後のステップに戻されます。このステップでは、publishProgress(Progress ...)を使用して、1つ以上の進行状況を公開することもできます。これらの値は、UIスレッドのonProgressUpdate(Progress ...)ステップで公開されます。
onProgressUpdate(Progress...)
、の呼び出し後にUIスレッドで呼び出されますpublishProgress(Progress...)
。実行のタイミングは未定義です。このメソッドは、バックグラウンド計算の実行中に、ユーザーインターフェイスであらゆる形式の進行状況を表示するために使用されます。
onPostExecute(Result)
、バックグラウンド計算が終了した後にUIスレッドで呼び出されます。バックグラウンド計算の結果は、そのメソッドのパラメーターとしてこのステップに渡されます。ビットマップをimageViewに設定し、ビューを無効にすることができます。
無効化は機能しません。画像のURIまたはURLまたはパスを一時的に変更し、必要なパスに戻すと機能します。たとえば、私が持っている場合
image_url="myhost/img.png";
himg.setImageURI(image_url, imageLoader);
私はこれを次のように更新できます:
himg.setImageURI(null, imageLoader);
himg.setImageURI(image_url, imageLoader)
使ってみましたinvalidate()
か?次のサイクルではなく、ビューをすぐに再描画するように強制します
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (!socket.isClosed()) {
imgArray = receiveImagebytes();
}
}
}).start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (!socket.isClosed()) {
runOnUiThread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
imageView.setImageBitmap(BitmapFactory.decodeByteArray(imgArray, 0, imgArray.length));
imageView.invalidate();
}
});