您的位置:首页 > 移动开发 > Android开发

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

2012-09-27 14:01 369 查看
无意间在子线程中对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来进行更新。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: