web-dev-qa-db-ja.com

ASyncTaskから親アクティビティ関数を呼び出す方法は?

setAccountAuthenticatorResultは、AccountAuthenticatorActivityを拡張するアクティビティから呼び出すことができます。私の活動はそれを拡張しますが、ASyncTaskを起動するため、このsetAccountAuthenticatorResultはASyncTaskから呼び出す必要があります(または、ASyncTaskの結果をメインスレッドに返す必要があります)。

どうやってするの?

以下のコードの何が問題になっていますか?

AsyncTask<Uri, Void, Bundle> task = new RetrieveAccessTokenTask(this, consumer, provider, prefs).execute(uri);

public class RetrieveAccessTokenTask extends AsyncTask<Uri, Void, Bundle> {
    private Context context;

    public RetrieveAccessTokenTask(Context context, OAuthConsumer consumer,
            OAuthProvider provider, SharedPreferences prefs) {
        this.context = context;
    }

    @Override
    protected void onPostExecute(Bundle result) {
        context.setAccountAuthenticatorResult(); // doesn't work

    }
19
LA_

AsyncTaskを作成するときに、新しいコンストラクターを追加して、Activityへの参照を渡すことができます。

AsyncTask myTask = new MyTask(this);

次に、AsyncTaskのonPostExecute()メソッドから、アクティビティのメソッドを呼び出すことができます。

public class MyTask extends AsyncTask<String, String, String>
{
    public MyActivity activity;

    public MyTask(MyActivity a)
    {
        this.activity = a;
    }

    //  ......

    protected void onPostExecute(String result)
    {
        activity.myMethod();
    }
}
70
Ollie C

インターフェースを使用

次の手順を実行します:

1)インターフェースを作成します

public interface AsyncTaskListener{

   public void updateResult(String result);

}

2)AsyncTaskでリスナーを使用します

DownloadSongTask extends AsyncTask<String,Integer,String>{

   private AsyncTaskListener listener;

   public DownloadSongTask(Context context)
   {
       listener= (AsyncTaskListener)context;    // Typecast 
   }

   @Override
   public void doInbackGround(String... params)
   {
       // Download code
       int downloadPerc = // calculate that
       publish(downloadPerc);   
   }

   @Override
   public void onPostExecute(String result)
   {
       listener.updateResult(String result);  // Use it 
   }

}

3)アクティビティにインターフェースを実装し、インターフェースメソッドをオーバーライドします

  public class YourActivity extends AppcompatActivity implements AsyncTaskListener{

  // Activity code //
  new  DownloadSongTask(this).execute("Paradise.mp3");  // this is how you start Task

  public void yourMethod(String arg)
  {
    // Your method related Stuff
  }

  @Override 
  public void updateResult(String result){
        yourMethod(result);
  }

}

インターフェースを使用する利点は?

これは長いアプローチのようですが、このアプローチを使用すると

疎結合のAsyncTaskを作成できます。つまり、AsyncTask内のコードを変更することなく、将来の任意のアクティビティで同じAsyncTaskを使用できます。

関連リンク:

よりよく理解するには、これを読むことができます [〜#〜] answer [〜#〜]

2
Rohit Singh