【问题标题】:AsyncTask never executes onPostExecuteAsyncTask 从不执行 onPostExecute
【发布时间】:2011-11-22 11:32:20
【问题描述】:

我正在尝试执行以下 AsyncTask :

private class TimeUpdateTask extends AsyncTask<List<mObject>, Integer, Void> {

        @Override
        protected Void doInBackground(List<mObject>... params) {
            mObject o;
            int i;
            int numChecked = 0;

            List<mObject> mObjects = params[0];
            while(true)
            {   
                if (isCancelled())
                {
                    Log.w("TAG", "task interrumped");
                    return null;
                }

                    for (i=0 ; i < mObjects.size() ; i++)
                    {
                        o = mObjects.get(i);
                        if (!o.isChecked())
                        {
                            o.calculateProgress();
                            if (o.isChecked())
                            {
                                numChecked++;
                            }
                        }
                    }
                publishProgress(numChecked);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }

            }
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void onProgressUpdate(Integer... param){
            int progressCompleted = param[0];

            ((ArrayAdapter<mObject>) EventListView.this.EventView.getAdapter()).notifyDataSetChanged();

            mMain.setProgressBarCompleted(progressCompleted);
        }

        /*This should execute*/
        @Override
        protected void onPostExecute(Void result) {
            Log.d("TAG","End onPostExecute");
         }

    }

所以当我在这个任务上调用cancel(false) 时,应该执行onPostExecute 但它永远不会。

代码有什么问题还是别的什么? 我在 SO 中查看了很多答案,似乎有 #5 AsyncTask 闲逛是正常的,即使您目前只使用一个(如我的情况)。

【问题讨论】:

  • 进一步了解其他 cmets / 答案 - 不要使用 while(true)。试试while(!isCancelled()) - 更有意义。
  • 谢谢,我也是这么想的:)

标签: android android-asynctask


【解决方案1】:

这里缺少 1 个大块,你必须了解。

来自开发者文档(见下方粗体字):http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)

尝试取消此任务的执行。此尝试将失败,如果 任务已完成、已被取消或无法 因其他原因被取消。如果成功了,这个任务有 调用取消时未启动,此任务不应运行。如果 任务已经开始,然后是 mayInterruptIfRunning 参数 确定执行此任务的线程是否应该是 试图停止任务而被打断。

调用此方法将导致 onCancelled(Object) 被调用 在 doInBackground(Object[]) 返回后的 UI 线程上。 来电 此方法保证永远不会调用 onPostExecute(Object)。 调用此方法后,您应该检查返回的值 isCancelled() 定期从 doInBackground(Object[]) 完成 尽早完成任务。

【讨论】:

  • 感谢您指出这一点。现在一切都变得更有意义了 :)
  • "调用此方法保证永远不会调用 onPostExecute(Object)。" - 正是为什么 OP 从来没有看到 onPostExecute(...) 方法被调用。 +1
【解决方案2】:

Android在任务取消时使用onCancelled(),不会调用onPostExecute!

【讨论】:

    【解决方案3】:

    我认为调用取消实际上取消了所有的执行,包括 onPostExecute。您应该使用自己的本地布尔变量并执行以下操作:

    private boolean shouldContinue = true;
    
    public void customCancel() 
    {
           shouldContinue = false;
    }
    

    然后在你的循环中这样做:

    if (!shouldContinue)
    {
        Log.w("TAG", "task interrumped");
        return null;
    }
    

    【讨论】:

    • 抱歉,这毫无意义 - 到 onCancelled() 被调用时,doInBackground(...) 方法已经终止,shouldContinue 与“循环”无关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多