AsyncTask 从不执行 onPostExecute

发布于 2024-12-17 16:35:36 字数 1959 浏览 0 评论 0原文

我正在尝试执行以下 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 挂在身边是正常的,即使您目前只使用一个(如我的情况)。

I am trying to execute the following 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");
         }

    }

So when I call cancel(false) on this task, onPostExecute should be executed but it never is.

Is there any problem in the code or something else?
I have looked at a lot of answers in SO and it seems that having #5 AsyncTask hanging around is normal, even if you are using only one (as in my case) at the moment.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

微凉徒眸意 2024-12-24 16:35:36

这里缺少一大块你必须了解的内容。

来自开发人员文档(请参阅下面的粗体文本): http:// developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)

尝试取消此任务的执行。如果出现以下情况,此尝试将会失败
任务已完成、已取消或无法
因其他原因被取消。如果成功,并且此任务已
调用取消时未启动,该任务永远不应该运行。如果
任务已经开始,那么mayInterruptIfRunning参数
确定执行此任务的线程是否应该
试图停止任务时被中断。

调用此方法将导致调用 onCancelled(Object)
doInBackground(Object[]) 返回后在 UI 线程上。 呼叫
此方法保证永远不会调用 onPostExecute(Object)。

调用此方法后,您应该检查返回的值
isCancelled() 定期从 doInBackground(Object[]) 完成
尽早完成任务。

There is 1 large piece missing here that you must learn about.

from the developer docs (see bold text below): http://developer.android.com/reference/android/os/AsyncTask.html#cancel(boolean)

Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, already been cancelled, or could not
be cancelled for some other reason. If successful, and this task has
not started when cancel is called, this task should never run. If the
task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.

Calling this method will result in onCancelled(Object) being invoked
on the UI thread after doInBackground(Object[]) returns. Calling
this method guarantees that onPostExecute(Object) is never invoked.

After invoking this method, you should check the value returned by
isCancelled() periodically from doInBackground(Object[]) to finish the
task as early as possible.

顾冷 2024-12-24 16:35:36

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

Android use onCancelled() when the task is cancelled, it don't call onPostExecute!

冷月断魂刀 2024-12-24 16:35:36

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

private boolean shouldContinue = true;

public void customCancel() 
{
       shouldContinue = false;
}

然后在循环中执行以下操作:

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

I think calling cancel actually cancels everything from executing, including the onPostExecute. You should use your own local boolean variable and do this:

private boolean shouldContinue = true;

public void customCancel() 
{
       shouldContinue = false;
}

then in your loop do this:

if (!shouldContinue)
{
    Log.w("TAG", "task interrumped");
    return null;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文