问题: Android是不允许子线程更新UI界面的,子线程更新界面会出现异常,然而下面的例子非常让人苦恼,‘子线程’更新UI界面,并且没有发生异常。
@Override
public void onClick(View arg0) {
Log.d(TAG, "onClick " + Thread.currentThread().getName());
new Thread(new Runnable() {
@Override
public void run() {
Log.d(TAG, "run " + Thread.currentThread().getName());
for(int i=0;i<=100;i ++) {
try {
mProgressBar.setProgress(i);
Thread.sleep(1000);
Log.d(TAG, "mProgressBar setProgress:" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
原因:在源码中ProgressBar中会调用到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;
}
}
}
从中可以得知如果当前线程id与UI线程不相等,则post到UI线程中的handler中,从而使UI线程更新界面,而不是自己写的子线程更新界面.