android ProgressBar ProgressDialog可以在子线程中更新的原理

本文探讨了在Android中从子线程更新ProgressBar和ProgressDialog的实现机制。通过分析源码,揭示了即使不在UI线程中,也能正确更新UI组件的原因。

无意间在子线程中对ProgressBar 进行了更新,发现应用能正常运行。

我们都知道控件只能在UI线程中进行更新,于是到网上搜啊搜啊,找不到答案,只能到源码中找。

一下是在源码中找到的一些代码,个人感觉应该是这个原理,有错误,请高手改正。

无论是调用ProgressBar的.incrementProgressBy(len)还是setProgress(len)
都是要调用下面这个方法:
private synchronized void refreshProgress(int id, int progress, boolean fromUser) {
        if (mUiThreadId == Thread.currentThread().getId()){//是否是UI线程,是的话直接更新
            doRefreshProgress(id, progress, fromUser);
        } else {//不是调用下面的post(r),r = new RefreshProgressRunnable
            RefreshProgressRunnable r;
            if (mRefreshProgressRunnable != null) {
                // Use cached RefreshProgressRunnable if available
                r = mRefreshProgressRunnable;
                // Uncache it
                mRefreshProgressRunnable = null;
                r.setup(id, progress, fromUser);
            } else {
                // Make a new one
                r = new RefreshProgressRunnable(id, progress, fromUser);
            }
            post(r);
        }
    }


private class RefreshProgressRunnable implements Runnable {
        public void run() {//核心回调的代码
            doRefreshProgress(mId, mProgress, mFromUser, true);
            // Put ourselves back in the cache when we are done
            mRefreshProgressRunnable = this;
        }
 
    }


post(r)----->执行到View的
 public boolean post(Runnable action) {
        Handler handler;
        if (mAttachInfo != null) {
            handler = mAttachInfo.mHandler;
        } else {
            // Assume that post will succeed later
            ViewRoot.getRunQueue().post(action);
            return true;
        }


        return handler.post(action);
    }


AttachInfo是View的一个内部类
  void dispatchAttachedToWindow(AttachInfo info, int visibility) {
        //System.out.println("Attached! " + this);
        mAttachInfo = info;
  }
}//这个方法应该是由系统的UI来调用,由系统传入info,处于UI线程。
上面post方法中handler.post(action);就可以更新UI了。




ProgressDialog也能在子线程中更新:
  public void incrementProgressBy(int diff) {
        if (mProgress != null) {
            mProgress.incrementProgressBy(diff);
            onProgressChanged();
        } else {
            mIncrementBy += diff;
        }
    }
这个mProgress生命在ProgressDialog的53行    
private ProgressBar mProgress;
也就是说,ProgressDialog更新UI调用的是ProgressBar来进行更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值