public class MainActivity extends Activity {
private TextView textview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
textview= (TextView) findViewById(R.id.textview);
new MyThread().start();
}
public class MyThread extends Thread{
@Override
public void run() {
textview.setText("子线程修改的");
}
}
}
在子线程中一般情况下是不能刷新UI的,但有一种情况可以。
在生命周期里,我们在setCotentView里面我所创建的DecorView并没有跟activity进行绑定,我们“UI在子线程可以setText”这个情况,这个问题其实是应该再UI刷新的时候去做的,一般有价值的刷新,activity刷新,要导致Window刷新,然后Window刷新带动DecorView去刷新,再而是DecorView刷新带动整个View去刷新,应该是这么一个逻辑,再这逻辑中间里面,我们的Window都还没有DecorView,也就是说再我整个UI体系里面,你这套体系根本就不存在,activity都还没有DecorView,没有DecorView的时候,你再去set一个Text,那么这个setText的操作能够出发我整个activity的view刷新吗?它会出发刷新吗?是不会的。因为activity和window和view的关系,那么你刷新UI的时候,整个UI刷新时由window来管理的,而这个window都不存在,activity对应的window都不存在,你怎么刷新呢。
同样的,它也能在onResume里执行线程里面setText。因为onCreate->onResume这阶段decorview都还没有跟activity绑定。ActivityThread调用handleResumeActivity,里面会先会通知activity去onResume,再去执行decorview都还没有跟activity绑定。
public final class ActivityThread extends ClientTransactionHandler {
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
}
}
@VisibleForTesting
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
....
r.activity.performResume(r.startsNotResumed, reason);
....
}
网友评论