这篇文章主要解答一些在平时学习工作过程中遇到的一些比较值得研究的问题。
1.DecorView是何时被创建的
是在PhoneWindow的generateDecor中被创建的
protected DecorView generateDecor() {
return new DecorView(getContext(), -1);
}
2.ViewRootImpl是何时被创建的
是在WindowManagerGlobal的addView方法中创建的
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
//省去大量代码
ViewRootImpl root;
View panelParentView = null;
//省去部分代码
root = new ViewRootImpl(view.getContext(), display);
......
}
3.Activity加载布局的流程
在Activity中调用setContentView加载布局,setContentView最终调用PhoneWindow的setContentView方法,在此方法中将根布局xml文件解析成View添加到DecorView中,然后从根布局文件中找到id为contente的父容器,将我们在setContentView中指定的布局文件通过inflate的方式添加进去
//将我们的布局文件添加到mContentParent中,这个mContentParent是根布局中id为content的一个FrameLayout
mLayoutInflater.inflate(layoutResID, mContentParent);
4.Window对象何时被创建
在Activity的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) {
attachBaseContext(context);
mFragments.attachActivity(this, mContainer, null);
//创建window对象
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
mWindow.setSoftInputMode(info.softInputMode);
}
if (info.uiOptions != 0) {
mWindow.setUiOptions(info.uiOptions);
}
mUiThread = Thread.currentThread();
.....
}
5.Application对象何时被创建
在Instrumentation的newApplication方法中
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
6.View绘制的起点在何处
ViewRootImpl的performTraversals方法
private void performTraversals() {
//省去海量代码
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
//省去部分代码
performLayout(lp, desiredWindowWidth, desiredWindowHeight);
//省去大量代码
performDraw();
.....
}
7.startActivity的流程
startActivity最终会调用startActivityForResult
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
....
}
实际调用的是Instrumentation的execStartActivity
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Fragment target,
Intent intent, int requestCode, Bundle options) {
//核心功能在这个whoThread中完成,其内部scheduleLaunchActivity方法用于完成activity的打开
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//真正打开activity的地方
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mWho : null,
requestCode, 0, null, null, options);
//对结果进行检查,抛异常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
IApplicationThread 看名字就知道是一个接口,我们找找实现类,
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
private class ApplicationThread extends ApplicationThreadNative
ApplicationThread 用来完成Activity各个状态的切换
8.DecorView何时被添加到Window中
在Activity的makeVisible方法中
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}