Как вызвать функцию родительской активности из ASyncTask?
setAccountAuthenticatorResult
можно вызвать из Activity, который продолжается 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
}
Ответы
Ответ 1
Когда вы создаете AsyncTask, вы можете добавить к нему новый конструктор и передать ссылку на Activity:
AsyncTask myTask = new MyTask(this);
И затем из метода onPostExecute() в AsyncTask вы можете вызвать метод в Activity.
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();
}
}
Ответ 2
Используйте интерфейс
Следуй этим шагам:
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) Реализовать интерфейс в методе Activity и Override.
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 можно использовать с любым действием, даже не меняя код в AsyncTask. Вот как вы создаете слабо связанную AsyncTask.
Соответствующие ссылки:
Для лучшего понимания вы можете прочитать этот ОТВЕТ