我在开始android开发(以及一般的初学者开发)时学到的第一件事是,除了主ui线程之外,ui不应该(在很多情况下也不能)被任何其他线程更新。
我有一个异步任务,它正在移动doinbackground()中的一堆文件。我有一个progressbar,它向用户表示这一点。
我决定尝试doinbackground()方法/线程中的progressbar.setprogress([updated progress]),出乎意料的是,它工作得很好。
然而,这似乎违背了我学到的惯例。我知道asynctask有一个onprogressupdate()或其他什么东西,但它让我有点困惑,我不确定它是否值得切换,因为当前的实现似乎工作正常。
我不应该更新这个后台线程中的progressbar吗?

最佳答案

ProgressBar能够在不崩溃的情况下执行此操作,因为setProgress()调用refreshProgress()(线程安全的方法),此时是真正刷新视图的时候。

private synchronized void refreshProgress(int id, int progress, boolean fromUser) {
        if (mUiThreadId == Thread.currentThread().getId()) {
            doRefreshProgress(id, progress, fromUser, true);
        } else {
            if (mRefreshProgressRunnable == null) {
                mRefreshProgressRunnable = new RefreshProgressRunnable();
            }

            final RefreshData rd = RefreshData.obtain(id, progress, fromUser);
            mRefreshData.add(rd);
            if (mAttached && !mRefreshIsPosted) {
                post(mRefreshProgressRunnable);
                mRefreshIsPosted = true;
            }
        }
    }

如果方法调用是非ui线程,它会向ui线程发送一个Runnable,从而避免CalledFromWrongThreadExceptions。
但是,始终使用ui线程进行ui相关的调用;android开发人员可以随时更改实现,并且视图通常不是线程安全的。

08-18 04:34
查看更多