优秀的编程知识分享平台

网站首页 > 技术文章 正文

android中真的不能在子线程中更新UI吗?

nanyue 2025-02-03 14:22:16 技术文章 5 ℃

我们一般接受的思想就是不要在子线程中更新UI,为什么呢?这你就不得不提到 activity的启动过程中的检查机制.

public void setContentView(View view, ViewGroup.LayoutParams params) {

// Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window

// decor, when theme attributes and the like are crystalized. Do not check the feature

// before this happens.

if (mContentParent == null) {

installDecor();

} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

mContentParent.removeAllViews();

}

if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

view.setLayoutParams(params);

final Scene newScene = new Scene(mContentParent, view);

transitionTo(newScene);

} else {

mContentParent.addView(view, params);

}

mContentParent.requestApplyInsets();

final Window.Callback cb = getCallback();

if (cb != null && !isDestroyed()) {

cb.onContentChanged();

}

}

执行完上面的setContentView后,DecorView还没有被WindowManager正式添加到Window中,接着会调用到ActivityThread类的handleResumeActivity方法将顶层视图DecorView添加到PhoneWindow窗口,handleResumeActivity中需要执行addView方法,WindowManagerImpl 将 addView操作交给WindowManagerGlobal来实现,WindowManagerGlobal的addView函数中创建了一个ViewRootImpl对象root,然后调用ViewRootImpl类中的setView成员方法,setView中主要做:

public void requestLayout() {

if (!mHandlingLayoutInLayoutRequest) {

checkThread();

mLayoutRequested = true;

scheduleTraversals();

}

}

我们看到有这个checkThread,他就是来保证我们必须在ui线程中更新view,那么是不是子线程就不能更新ui了呢,,并不是这样的,你在oncreate中执行ui更新时:

(new Thread(){

@Override

public void run() {

super.run();

Log.e("pid",Thread.currentThread().getId()+"");

((TextView)findViewById(R.id.keep)).setText("测试代码");

}

}).start();

checkThread方法没执行到,这时候你相当于可以设置ui,但是你设置线程sleep几秒后,在更新,就会报错,只适合checkTread已经执行到了。

Tags:

最近发表
标签列表