web-dev-qa-db-ja.com

Android AsyncTaskが終了するのを待つ

関数AppHelper.isOnline(Context context)があります。アプリケーションのさまざまな部分を呼び出して、HTTPリクエストを行う前にセッションがタイムアウトしなかったことを確認します。

_public void onClick(View v) {
        Intent intent = null;
        switch (v.getId()) {

        case R.id.buttonPagamenti:
            if (AppHelper.isOnline(this))
            {
                //here AppHelper.isOnline should have finished it's async task
                intent = new Intent(this, OrdineCreaActivity.class);
                this.startActivityForResult(intent, R.id.buttonPagamenti);
            }
            break;
...
_

AppHelper.isOnline()の内部で、ログインするAsyncTaskを実行しているため、ネットワーク要求を作成しています。そうしないと例外が発生するため、UIで実行できません。 if内のコードで再開する前に完了するまで待つ必要があります。これどうやってするの ?

問題は、アクティビティが最初に開始され、その後AsyncTaskが実行されるため、アクティビティが有効なログインセッションを期待しているときに中断することです。

37
max4ever

次の2つのオプションがあります。

AsyncTaskのメソッドget(long timeout, TimeUnit unit)を次のように使用します。

_task.get(1000, TimeUnit.MILLISECONDS);
_

これにより、メインスレッドはAsyncTaskの結果を最大で1000ミリ秒待機します(@ user1028741のコメントによると:実際には待機メソッドもあります- AsyncTask#get() =場合によっては作業を行うこともあります)。

または、完了するまで非同期タスクに進捗ダイアログを表示できます。これを参照してください thread (コードを過ぎてコピーする必要はありません)。基本的に、非同期タスクの実行中は進捗ダイアログが表示され、終了すると非表示になります。

3番目のオプションもあります。 "Threadがニーズに十分であれば、そのjoinメソッドを使用できます。ただし、タスクの進行に時間がかかる場合は、進行状況を表示する必要がありますそれ以外の場合は、メインスレッドが長時間アクティブでないために例外が発生します。

81
Boris Strandjev

使ってみて

if (AppHelper.isOnline(this))
        {
            while(!task.isCancelled()){
               // waiting until finished protected String[] doInBackground(Void... params)          
              } 
            intent = new Intent(this, OrdineCreaActivity.class);
            this.startActivityForResult(intent, R.id.buttonPagamenti);
        }    

詳細については、 http://developer.Android.com/reference/Android/os/AsyncTask.html を参照してください。

3
Rafiq

Rafiqの応答は私にはうまくいきませんでした-アプリがハングしました。その理由はisCancelled()の性質に関係していると思います:「このタスクが正常に完了する前にキャンセルされた場合、trueを返します。」タスクが正常に完了する(つまり、キャンセルされない)場合、while(!task.isCancelled()) { }は永久にループします。

これを解決するには、falseにインスタンス化するブールフラグを作成し、task.onPostExecute()trueに切り替えます。次に、アクティビティを切り替える前にwhile(!flag) { }を実行します。また、メインスレッドに「ブレーク」を与えてAsyncTaskプロセスを少し速くしたい場合は、これを試すことができます。

while (!flag) {
    try { Thread.sleep(100); }
    catch (InterruptedException e) { e.printStackTrace(); }
}

私にとってはうまく機能しているようです。

1
Mark Cramer
intent = new Intent(this, OrdineCreaActivity.class);
context.startActivityForResult(intent, R.id.buttonPagamenti);

AysncTaskのonPostExecute()に上記の行を記述します。 AsyncTaskを使用している場合、タスクが完了するまでそこで待機しないためです。

1
Shankar Agarwal