2

我在开始 android 开发(以及一般的初学者开发)时学到的第一件事是 UI 不应该(并且在许多情况下不能)由除了主 UI 线程之外的任何其他线程更新。

我有一个 AsyncTask 正在其 doInBackground() 中移动一堆文件。我有一个向用户表示的进度条。

为了它(主要是由于懒惰),我决定在 doInBackground() 方法/线程中尝试 progressBar.setProgress([updated progress]) ,令我惊讶的是,它工作正常。

然而,这似乎违背了我所学到的惯例。我知道 AsyncTask 有一个 onProgressUpdate() 或其他什么,但这让我有点困惑,而且我不确定它是否值得切换,因为当前的实现似乎工作正常。

我不应该在这个后台线程中更新进度条吗?

4

2 回答 2

3

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;
            }
        }
    }

Runnable如果方法调用是非 UI线程,它会将 a 发布到 UI线程,避免CalledFromWrongThreadExceptions。

但是,始终使用 UI 线程进行 UI 相关调用;Android 开发人员可以随时更改实现,并且视图通常不是线程安全的。

于 2013-08-26T21:22:13.987 回答
1

您不应ProgressBar直接从内部修改和/或调用其任何方法doInBackground(),因为 Android UI 工具包不是线程安全的。

相反,publishProgress()从内部调用doInBackground(),您将在 UI 线程上收到后续回调onProgressUpdate(),您可以在其中随意修改ProgressBar

于 2013-08-26T21:24:13.000 回答