#android #android-asynctask
#Android #android-асинхронная задача
Вопрос:
Как вернуть значение в основное действие после выполнения другой асинхронной задачи в onPostExecute()?
Я написал функцию во 2-й асинхронной задаче, чтобы вернуть ArrayList обратно в 1-ю асинхронную задачу. Однако я не знаю, как вернуть список массивов из 1-й асинхронной задачи обратно в основное действие.
//Main Activity:
DownloaderGet downloaderGet = new DownloaderGet(getActivity(), "http://xxxxx.php");
downloaderGet.execute();
//1st AsyncTask(DownloaderGet)
@Override
protected void onPostExecute(String jsonData) {
super.onPostExecute(jsonData);
new DataParserGet(c, jsonData).execute();
}
//2nd Asynctask(DataParserGet)
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
pd.dismiss();
if(result)
{
myNewArrayList = spacecrafts;
passToClass();
}
}
Ответ №1:
Вы можете сделать это, выполнив следующие шаги
Создайте interface
public interface AsyncResponse {
void passToClass(Boolean output);
}
Вы можете изменить параметр passToClass() по своему усмотрению.
Объявите экземпляр AsyncResponse
в вашей асинхронной задаче
public AsyncResponse delegate = null;
В onPostExecute
delegate.passToClass(result);
Затем заставит вас Activity
реализовать AsyncResponse
public class MainActivity implements AsyncResponse
Наконец, переопределите свой метод и получите ваш результат в вашем Activity
@Override
void passToClass(Boolean output){
//here you get the reuslt from AsyncTask
}
Комментарии:
1. Поступая таким образом, собираюсь ли я передать результат прямо в мое основное действие, не передавая его обратно в 1-ю асинхронную задачу правильно? Пожалуйста, поправьте меня, если я ошибаюсь
2. Вы пробовали это? Если я вас правильно понял, нет, вы получите результат в своем основном действии только тогда, когда он установлен в асинхронной задаче
Ответ №2:
Проблема: Вы хотите передать список массивов из второй асинхронной задачи обратно в MainActivity.
Решение: передача экземпляра activity первой асинхронной задаче, затем пересылка экземпляра второй асинхронной задаче.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Pass `this` as activity instance to the first AsyncTask.
DownloaderGet downloaderGet = new DownloaderGet(this, "http://xxxxx.php");
downloaderGet.execute();
}
public void onDataAvailable(List<String> arrauList) {
// Process array list here.
}
}
// The first AsyncTask.
class DownloaderGet extends AsyncTask<Void, Void, String> {
private WeakReference<MainActivity> activity;
private String url;
DownloaderGet(MainActivity activity, String url) {
this.activity = new WeakReference<>(activity);
this.url = url;
}
@Override
protected String doInBackground(Void... voids) {
// Your code here
// ...
return null;
}
@Override
protected void onPostExecute(String jsonData) {
// Forward the instance to the second AsyncTask.
new DataParserGet(activity.get(), jsonData).execute();
}
}
class DataParserGet extends AsyncTask<Void, Void, Boolean> {
private WeakReference<MainActivity> activity;
private String jsonData;
DataParserGet(MainActivity activity, String jsonData) {
this.activity = new WeakReference<>(activity);
this.jsonData = jsonData;
}
@Override
protected Boolean doInBackground(Void... voids) {
// Your code here
// ...
return null;
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
myNewArrayList = spacecrafts;
if (activity.get() != null) {
// Pass the array list back to main activity.
activity.get().onDataAvailable(myNewArrayList);
}
}
}
}
Ответ №3:
Asynctask используется для выполнения длительных операций.
Если вы уже используете одну асинхронную задачу, вам не нужна другая асинхронная задача. Попробуйте поместить весь этот второй код асинхронной задачи внутрь первого.
public void doInBackground(){
//Sample1
//Dependent code waiting for sample1 to finish
}
Вы можете дождаться завершения некоторого кода, который вы можете ввести в другой фрагмент кода, все внутри только одной асинхронной задачи.
Чтобы вернуть некоторый код в MainActivity из asynctask, используйте обратный вызов с использованием интерфейса.
- Создать интерфейс
public interface MyTaskCallback{
void myResultData();
}
- Реализовать интерфейс в пункте назначения. В вашем случае адресатом является MainActivity.
public void MainActivity extends AppCompatActivity implements MyTaskCallback{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//Start the task. Pass interface reference in the constructor of the task
new MyTask(MainActivity.this).execute();
}
}
- Передает ссылку на интерфейс конструктору AsyncTask из Activity
public void MyTask extends AsyncTask<Void, Void, Void>{
private MyTaskCallback myTaskCallback;
public MyTask(myTaskCallback){
this.myTaskCallback = myTaskCallback;
}
public void onPostExecute(){
if(myTaskCallback != null)
myTaskCallback.myResultData();
}
}