等待其他AsyncTasks'在处理onPostExecute之前在AsyncTask中完成

时间:2016-09-02 09:57:37

标签: java android android-asynctask

我从网址获取信息并将该信息发送到多个网址。我正在" for"在AsyncTask中,在第一个AsyncTask的onPostExecute中,我更改了一个TextView并告诉"全部已完成"给用户。

但即使AsyncTask的孩子继续被执行,父亲AsyncTask也会执行onPostExecute。所以我需要等待他们,我一直坚持下去。

所以,我有两个AsyncTask类。这是我发给网站的课程:

class SendTo extends AsyncTask <Object,Object,String>{

    @Override
    protected String doInBackground(Object... strings) {
        ....
    }
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        //update ui for gathered information
    }

}

这是我从网站获得的任务:

class GetFrom extends AsyncTask <Object,Object,String>{

    @Override
    protected String doInBackground(Object... strings) {
        ....
        String param = anotherMagicalFunctionThatGivesParamToSend(strings[1]);
        for(i = 1; i < websites.length; i++){
            publishProgress(websites[i],param);
        }
        return "";
    }
    protected void onProgressUpdate(final Object... values) {
        super.onProgressUpdate(values);
        new SendTo().executeOnExecutor(THREAD_POOL_EXECUTOR, values[1], values[0]);
    }
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        //finish things
    }
}

4 个答案:

答案 0 :(得分:2)

我建议在这种情况下使用回调。

创建一个界面:

$onChanges

头等舱:

public interface MyCallback {
    public void readycallback(int index_thread);
}

第二课:

    class SendTo extends AsyncTask <Object,Object,String>{
private    MyCallback cb;
private int i;
public SendTo(int i, MyCallback cb) {
this.cb = cb;
this.i = i;
}
        @Override
        protected String doInBackground(Object... strings) {
            ....
        }

        protected void onPostExecute(String s) {
            super.onPostExecute(s);
if (cb != null)
cb.readycallback(i);
            //update ui for gathered information
        }

    }

或者使用Threads获得更好的编码风格。但我真的认为使用 class GetFrom extends AsyncTask <Object,Object,String>{ private boolean[] array_of_completed_tasks = new boolean[websites.length - 1]; @Override protected String doInBackground(Object... strings) { .... String param = anotherMagicalFunctionThatGivesParamToSend(strings[1]); for(i = 1; i < websites.length; i++){ publishProgress(websites[i],param); } while(!checkIfAllThreadAreCompleted()) { //waiting all threads //you can wait try { Thread.sleep(10L);// ten milliseconds } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return ""; } protected void onProgressUpdate(final Object... values) { super.onProgressUpdate(values); new SendTo(i, new MyCallback() { @Override public void readycallback(int index_thread) { //this is your ready callback array_of_completed_tasks[index_thread] = true; } }).executeOnExecutor(THREAD_POOL_EXECUTOR, values[1], values[0]); } } private boolean checkIfAllThreadAreCompleted() { boolean ok = true; for(i = 0; i < array_of_completed_tasks.length; i++){ ok = ok && array_of_completed_tasks[i]; } return ok; protected void onPostExecute(String s) { super.onPostExecute(s); //finish things } } 非常难看的方法是真正的项目。

答案 1 :(得分:1)

  1. for loop的{​​{1}}内运行postExecute(),因为在asyncTask内运行thread无效。

  2. 维护一个thread,其中包含已完成global variable的计数,并且当每个asyncTasks完成执行时,将增加1。即它会进入asyncTask

  3. 在每个postExecute检查该计数是否等于网站数量。如果该数字等于基本上意味着您的所有数据成功postExecute的网站数量,那么它仍在进行中。

答案 2 :(得分:1)

让一个julia> a = [[1, 2], [3, 4]] 2-element Array{Array{Int64,1},1}: [1,2] [3,4] julia> VERSION v"0.5.0" 等待其他AsyncTask完成可能不是一个好主意。它使代码更加复杂,并且在它等待时阻止在池中使用该线程。

如果可以,您可以更简单地并行启动所有AsyncTask并让它们在AsyncTask中调用相同的方法。然后,该方法将检查是否已发布所有onPostExecute()的所有结果并显示&#34;所有已完成&#34;在那种情况下。

如果你真的希望在AsyncTask中有一个AsyncTask等待一个或多个其他doInBackground()完成(有效地暂停后台线程),你可以使用标准的Java同步机制。我建议使用CountDownLatch

值得注意的是,使用 RxJava 可以很容易地实现后台任务之间的同步,而不是使用专为简单用例设计的AsyncTask。< / p>

答案 3 :(得分:0)

您可以在子asyncTask中传递TextView并在子asynchTask的onPost方法中更新其值。