在前两篇文章中我们谈到了从桌面点击图标到启动进程以及启动ActivityThread再到ActivityThread启动Activity的过程分析
1. 安卓应用启动流程分析
2. ActivityThread启动页面分析
本片文章可谓是紧接着上面两篇文章,上文说到的ActivityThread performLaunchActivity(),今天继续讲从这里如何创建Activity 的。
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
。。。
if (r.profileFd != null) {
mProfiler.setProfiler(r.profileFile, r.profileFd);
mProfiler.startProfiling();
mProfiler.autoStopProfiler = r.autoStopProfiler;
}
handleConfigurationChanged(null, null);
//上节提到,我们ActivityThread开启来之后呢,开启Activity 的入口在这里,那么我们还是继续深入其中,看看他又做了什么操作。
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward);
。。。
} else {
try {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null);
} catch (RemoteException ex) {
// Ignore
}
}
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
//首先通过Intent获取到Activity 的相关信息
if (component == null) {
component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
//此处 mInstrumentation通过newActivity的方法获取到一个Activity的实例
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity( cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//ContextImpl创建,这个类单独讲
if (activity != null) {
ContextImpl appContext = new ContextImpl();
appContext.init(r.packageInfo, r.token, this);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//这里很重要,attach方法绑定的是谁呢? 你想 目前还没有绘制页面还没有添加到窗体
//所以说 会创建window绑定 并绑定WindowManagerService
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//到了这里开始 调用调用Activity的 onCreate方法。
mInstrumentation.callActivityOnCreate(activity, r.state);
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
}
return activity;
}
上面给出了简单的注释,应该都可以看懂,那么现在很明显最重要的看看attach方法里面主要做了什么。
首先看Instrumentation 如何创建Activity
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
//这里你就明白了,怎么获取的Activity实例
return (Activity)cl.loadClass(className).newInstance();
}
//下来看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);
//这个版本还是基于API——15的,新版本的会有些差别。
//这里创建了Window 并获取到了WindowManager
mWindow = PolicyManager.makeNewWindow(this);
//提一句 public Window makeNewWindow(Context context) {
// return new PhoneWindow(context);
//}
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();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mIdent = ident;
mApplication = application;
mIntent = intent;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
mWindow.setWindowManager(null, mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null) {
mWindow.setContainer(mParent.getWindow());
}
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
}
今天内容就超级简单了,我们总结下就是ActivityThread里面通过ActivityManagerService、 H、ApplicationThread 的操作最终走到了 performLaunchActivity ,通过Instrumentation调用反射获取到了Activity的对象,尔后 创建了Window 并调用了onCreate方法,那我们知道onCreate方法里面我们一般写的是啥啊? 不就是setContentView()吗,也就是开始了真正的绘制之路,绘制的路程少不了WindowManagerService 对吧,上面我们已经创建了Window,似乎已经很近了不是,今天就到这里,下一篇看Activity的绘制流程!