注意:鄙人看的是6.0的代码
Activity里面还是调用了WindowManager来显示界面。在activity的738行,有这几行代码
private Window mWindow;
private WindowManager mWindowManager;
/*package*/ View mDecor = null; //这就是activity的主view,我也不知道怎么表达会比较好 = =
平常用的setContentView方法,最终是调用了mWindow来处理的。
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
mWindow其实一个 PhoneWindow对象,在6169行的attach方法可是看到它的初始化
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
mWindow = new PhoneWindow(this);//我在这里
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
...
}
其中mWindowManager是通过mWindow来实现初始化
mWindowManager = mWindow.getWindowManager();
接着看看activity是怎么调用mWindowManager来显示界面,在源码第4772行,可以看到一个setVisible方法,这就是activity展示界面的入口吧
public void setVisible(boolean visible) {
if (mVisibleFromClient != visible) {
mVisibleFromClient = visible;
if (mVisibleFromServer) {
if (visible) makeVisible();//我将要展示界面
else mDecor.setVisibility(View.INVISIBLE);
}
}
}
接着看看makeVisible方法是怎么调用mWindowManager来显示界面。没错,其实就是用addview来显示界面。
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
为什么activity能通过android:configChanges="orientation|keyboardHidden" ,能保证界面不重建呢,我们可以看到源码还有一个onWindowAttributesChanged方法。
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
// Update window manager if: we have a view, that view is
// attached to its parent (which will be a RootView), and
// this activity is not embedded.
if (mParent == null) {
View decor = mDecor;
if (decor != null && decor.getParent() != null) {
getWindowManager().updateViewLayout(decor, params);
}
}
}
我估计是用了updateViewLayout来刷新页面,单纯看到这里,activity是怎么监听屏幕旋转呢?