Android在另一个完成后调用AsyncTask

hcp*_*ter 28 android android-asynctask

我对Android AsyncTask有一些问题.有一个Activity包含一些TextView按钮和图片.当用户输入此活动时,我启动一个asynctask来检查用户是否可以从活动开始(直到任务没有完成按钮未激活).然后我想开始另一个asyntask来获取图片.所以我做了一个内部课:

AsyncTask<String, Void, JSONObject>() authTask = new AsyncTask<String, Void, JSONObject>() {
     @Override
     protected JSONObject doInBackground(String... params) {
         //call the rest api
     }
     @Override
     protected void onPostExecute(JSONObject result) {
         // check the result
         // and make another asynctask
         AsyncTask<String, Void, Bitmap> imageTask = new Async.... {
             // get image
         }
         imageTask.execute();
     }
}
Run Code Online (Sandbox Code Playgroud)

authTask.execute(); 从UI线程调用 .

我对此有一种不好的感觉,特别是它看起来不起作用(它好几次但是突然它"冻结":只是挂起并且进度条正在旋转也没有例外.没有任何反应,按钮也不会激活.)还有另一种获取信息的方法,当它完成后立即启动另一项任务?

UDPATE:我使用的是api级别10.在authTask中,我获得了启动imageTask(一些id)所需的一些信息,所以我必须连续调用这些任务.在api 10级这是可能的吗?

提前致谢!

彼得

ρяσ*_*я K 27

您可以使用getStatus()检查是否AsyncTask挂起,正在运行或已完成.当finsh启动您的新任务时.如:

if(authTask .getStatus() == AsyncTask.Status.PENDING){
    // My AsyncTask has not started yet
}

if(authTask .getStatus() == AsyncTask.Status.RUNNING){
    // My AsyncTask is currently doing work in doInBackground()
}

if(authTask .getStatus() == AsyncTask.Status.FINISHED){
    // START NEW TASK HERE
}
Run Code Online (Sandbox Code Playgroud)

您的应用的示例:

btn.setOnClickListener(new View.OnClickListener()
  {
    public void onClick(View v)
      {
        if (authTask != null && authTask.getStatus() == AsyncTask.Status.FINISHED) {
           //START YOUR NEW TASK HERE
        }
        else
        {
          //IGNORE BUTTON CLICK
        }
      }
   }); 
Run Code Online (Sandbox Code Playgroud)


Pet*_*tai 21

1:

你可以在一个单独的一个中编写authTask的代码,然后一个接一个地编写imageTask的代码doInBackground().单个AsyncTask实例将由单个execute()语句触发.根据所需的UI交互,这可能是也可能不实用.


2:

编辑:如kabuku所述,此信息主要用于HoneyComb +.Pre HoneyComb我肯定会选择上面的选项1.executeOnExecutor()是api level 11+

在最新版本中,execute()默认情况下将发送AsyncTasks(ICS +).如果要确保发生这种情况,请指定串行执行程序.

在你的情况下,这将是:

authTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
// Image task will only be done AFTER textViewTask is done
imageTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
Run Code Online (Sandbox Code Playgroud)

而对于较新的版本来说简单

...
// ICS+ and pre honeycomb (I think)
authTask.execute();
// Image task will only be done AFTER textViewTask is done
imageTask.execute();
...
Run Code Online (Sandbox Code Playgroud)

AsycnTask.execute()文档:

注意:此函数根据平台版本为单个后台线程或线程池调度队列上的任务.首次引入时,AsyncTasks在单个后台线程上串行执行.从DONUT开始,这被改为一个线程池,允许多个任务并行运行.在HONEYCOMB之后,计划将其更改回单个线程以避免由并行执行引起的常见应用程序错误.


PS:要独立运行任务,必须使用AsyncTask.THREAD_POOL_EXECUTOR.这需要一个不同的执行者:

// Go parallel! (NOT what you want)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
Run Code Online (Sandbox Code Playgroud)


waq*_*lam 5

嵌套 AsyncTask 并不是一个好的设计。在doInBackground 中完成所有繁重的工作,然后简单地发布/更新结果。换句话说,在你的第一个 AsyncTask 中结合第二个 AsyncTask 的处理。


归档时间:

查看次数:

36602 次

最近记录:

7 年,7 月 前