UI线程上的AsyncTask不更新

Ant*_*ony 5 user-interface android thread-safety android-asynctask

我有一个AsyncTask更新ActionBarSherlock进度实现.不知怎的,onProgressUpdate虽然声称在UI线程上执行,却引发了一个线程错误.

protected void onProgressUpdate(Integer... values)
{
    setSupportProgress(values[0]);
}
Run Code Online (Sandbox Code Playgroud)

错误是:

03-06 00:13:11.672:E/AndroidRuntime(4183):at com.anthonymandra.framework.GalleryActivity $ ShareTask.onProgressUpdate(GalleryActivity.java:476)

只有创建视图层次结构的原始线程才能触及其视图.

据我所知,我应该访问UI线程...

我在我的应用程序中有很多工作AsyncTasks,但是根据要求这里是doInBackground(简化):

for (MediaObject image : toShare)
{
    BufferedInputStream imageData = image.getThumbStream();
    File swapFile = getSwapFile(...);
    write(swapFile, imageData);
    ++completed;
    float progress = (float) completed / toShare.size();
    int progressLocation = (int) Math.ceil(progressRange * progress);
    onProgressUpdate(progressLocation);
}
Run Code Online (Sandbox Code Playgroud)

Sim*_*all 4

好吧,问题是当你应该调用publishProgress 时,你却调用了onProgressUpdate。OP自己解决了这个问题,所以我只是复制粘贴它,这样他/她就不需要等待接受答案。下面是 AsyncTasks 如何工作的信息,这是很好的知识。


您是AsyncTask在 UI 线程上创建的吗?如果你不是,那就是问题所在。onProgressUpdate将在创建AsyncTask.

更新:让我们有一些代码挖掘时间(API 15 源代码)!

protected final void publishProgress(Progress... values) {
    if (!isCancelled()) {
        sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
                new AsyncTaskResult<Progress>(this, values)).sendToTarget();
    }
}
Run Code Online (Sandbox Code Playgroud)

这个家伙将其称为静态HandlersHandler。文档

当您创建一个新的处理程序时,它会绑定到创建它的线程的线程/消息队列 - 从那时起,它将向该消息队列传递消息和可运行对象,并在它们从消息中出来时执行它们队列。

感谢 Bruno Mateus 的文档查找技巧:

看,我在文档页面找到:线程规则 - 为了使此类正常工作,必须遵循一些线程规则: - AsyncTask 类必须加载到 UI 线程上。从 JELLY_BEAN 开始,这是自动完成的。- 任务实例必须在UI线程上创建。必须在 UI 线程上调用execute(Params...)。- 不要手动调用 onPreExecute()、onPostExecute(Result)、doInBackground(Params...)、onProgressUpdate(Progress...)。- 该任务只能执行一次(如果尝试第二次执行,将抛出异常。)