从asynctask获取结果并处理它

时间:2016-11-04 13:38:22

标签: java android multithreading android-asynctask

我看到很多关于从异步任务中获取结果的问题,但没有一个能解决我的问题。我想要做的是从MyClass对象的异步任务数组中获取并在UI中使用它们,但在不同情况下我有不同的UI。有时我用我的数组填充recyclerview,有时我用我的数组填充无限的标签活动。这意味着我无法将我的UI元素传递给Async任务,以便在onPostExecute()中处理它。我想从Async任务得到的结果就是MyClass对象的数组,然后在不同的情况下以不同的方式使用它。还有一件重要的事情是,我应该在AsyncTask执行后填充我的UI(因为如果它仍在执行我没有数据来填充UI),所以我不能简单地写一些像

MyClass[] result = new MyAsyncTask().execute().getResult()
MyUI.fillWith(result)

因为我很可能会得到NPE。

那么我怎样才能将我的结果作为MyClass对象的数组返回并且只有在得到结果后才用它填充我的UI(所以在UI线程中我应该得到的信息是我的asynctask做了所有的工作,只有在那之后我才能用我的数据填充UI。当然我不想阻止我的UI线程)?

由于我之前写的原因,处理onPostExecute()中的UI无法解决我的问题。用界面覆盖AsyncTask似乎也不像我需要的东西。我看到了AsyncTask的唯一令牌解决方案,但我没有得到它的工作方式。

1 个答案:

答案 0 :(得分:3)

不是将UI元素直接传递给AsyncTask,而是创建一个表示任务完成后要执行的操作的界面:

public interface MyTaskHandler {
  void onComplete(MyClass[] results);
}

让您的任务接受此界面并在onPostExecute中调用它:

public class MyTask extends AsyncTask<..., ..., MyClass> {
  private MyTaskHandler myTaskHandler;

  public MyTask(MyTaskHandler myTaskHandler) { 
    this.myTaskHandler = myTaskHandler;
  }

  @Override
  public void onPostExecute(MyClass[] results) {
    myTaskHandler.onComplete(results);
  }
}

(在实际实现中,您需要使用WeakReferences或在销毁活动时将引用置空,就像处理视图一样,因为您的处理程序将生成对某些视图的引用)

然后,您可以根据您要执行的操作传递MyTaskHandler的不同实现:

public class MyActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    new MyAsyncTask(new MyTaskHandler() {
      @Override
      public void onComplete(MyClass[] results) {
        // load into list view
      }
    }).execute();

    new MyAsyncTask(new MyTaskHandler() {
      @Override
      public void onComplete(MyClass[] results) {
        // load into tabs
      }
    }).execute();
  }
}