任意のサーバーからJSONを取得しているときにprogressDialogを表示したいと思います。そのため、私はソリューションとしてAsyncTaskを使用していました(別の方法はわかりません)。
AsyncTaskインスタンスを使用して.get()メソッドを呼び出すまで、ProgressDialogは正常に機能します。どういうわけかUIをブロックしていると思います。これが私のAsyncTaskです:
public class myAsync extends AsyncTask<String, String, List> {
String message; // for dialog message
ProgressDialog progress;
Intent myIntent;
Context ctx;
public myAsync(String message, Context ctx) {
this.message = message;
this.ctx = ctx;
progress = new ProgressDialog(ctx);
}
@Override
protected void onPreExecute() {
progress.setMessage(message);
progress.setIndeterminate(true);
progress.setCancelable(false);
progress.show();
}
@Override
protected List doInBackground(String... params) {
//returns any list after the task
return anyList;
}
@Override
protected void onPostExecute(List result) {
if(progress.isShowing())
progress.dismiss();
}
}
そして、これがAsyncTaskを呼び出すmyActivityです。
myAsync asyncTask = new myAsync("Loading...", this);
asyncTask.execute("Any string", "Other string");
asyncTask.get(); // If I comment out this line, ProgressDialog works
実行後、doInBackgroundとonPostExecuteの両方の結果をログに記録しようとしても、問題はありません。しかし、.get()を使用して取得したい場合、結果のProgressDialogは表示されないか、表示される時間が非常に短い(おそらく0.2秒)
どうしたの?
はい、get()
waits必要に応じて計算が完了し、その結果を取得します。これは、UIスレッドをブロックし、結果を待っていることを意味します。
解決策:get
を呼び出さないでください
通常、postExecute
で関数(コールバック)を呼び出します。
.get()
を呼び出すと、現在のスレッド(UIスレッド)が待機するため、AsyncTask
が有効な「SyncTask
」に変更されます。 AsyncTask
が処理を完了するまで。 UIスレッドをブロックしているため、ProgressDialog
の.show()
メソッドの呼び出しでは、ダイアログがそれ自体に画面を描画できるようにする機会はありません。
呼び出しを削除すると、バックグラウンドで正しく実行できるようになります。
タスクの完了後に処理を行う必要がある場合は、タスクをonPostExecute
メソッド自体に配置するか、Activity
からonPostExecute
へのコールバックを使用することをお勧めします。
私があなたの質問を正しく理解している場合は、ProgressDialog
でAsyncTaskの進行状況を更新する必要がありますが、これは現在機能していません。したがって、注意すべき点がいくつかあります。.get()
で何を達成しようとしているのかわかりませんが、進行状況を表示したいと思います。
以下のプログラムを変更して、AsyncTaskの進行状況に合わせてUIスレッドを更新しました。 pdate進行状況が必要になるたびに、prog
メソッドでそのdoInBackground
変数を更新します。
public class myAsync extends AsyncTask<String, Integer, List> {
String message; // for dialog message
ProgressDialog progress;
Intent myIntent;
Context ctx;
public myAsync(String message, Context ctx) {
this.message = message;
this.ctx = ctx;
progress = new ProgressDialog(ctx);
}
@Override
protected void onPreExecute() {
// Runs on the UI thread
progress.setMessage(message);
progress.setIndeterminate(true);
progress.setCancelable(false);
progress.show();
}
@Override
protected List doInBackground(String... params) {
// Runs in the background thread
// publish your progress here!!
int prog = 5; // This number will represent your "progress"
publishProgress(prog);
return anyList;
}
protected void onProgressUpdate(Integer... progress) {
// Runs in the UI thread
// This method will fire (on the UI thread) EVERYTIME publishProgress
// is called.
Log.d(TAG, "Progress is: " +progress);
}
@Override
protected void onPostExecute(List result) {
// Runs in the UI thread
for (int i=0; i<result.size(); i++) {
Log.d(TAG, "List item: " + result.get(i));
}
if(progress.isShowing())
progress.dismiss();
}
}