我看到很多关于从异步任务中获取结果的问题,但没有一个能解决我的问题。我想要做的是从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的唯一令牌解决方案,但我没有得到它的工作方式。
答案 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();
}
}