本文来自最近闲暇时查看android framework源码写的一篇文章,可能有错误之处,烦请各位大神指正。
整个Activity的启动创建过程是通过ActivityThread完成的,首先看一下ActivityThread中的main方法:
public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter());
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
// 创建ActivityThread实例
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
AsyncTask.init();
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
}
ActivityThread中的main()方法中对一个Looper对象进行初始化,形成一个消息循环,通过Looper.prepareMainLooper()和Loop.loop()实现
然后再调用thread.attach方法,
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
.....
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//与ActivitymanagerService进行通信
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3*dalvikMax)/4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
+ " total=" + (runtime.totalMemory()/1024)
+ " used=" + (dalvikUsed/1024));
mSomeActivitiesChanged = false;
try {
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
}
……
}
通过ActivityManagerNative创建一个IActivityManager 以及ApplicationThread的实例mAppThread和ActivityManagerService进行交互,因为ActivityManagerService运行在一个独立的线程中,他是在zygote进程开启后创建的,该来用来跟zygote进程通信,从而创建对应的应用程序。ActivityManagerService跟应用程序交互就是通过ActivityManagerNative以及ApplicationThread实现的。ActivityManagerNative是继承自Binder的,首先ActivityThread获取AMSProxy,然后调用attachApplication函数将ActivityThread中创建的ApplicationThread传递给AMS,AMS会根据pid找到对应的ProcessRecord,然后将ApplicationThread保存在ProcessRecord.thread中
任何主线程的操作都会发送到这个Looper对应的Handler中去,它是ActivityThread中定义的一个内部类,名为H,继承自Handler。代码如下:
private class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
...
}
该handleLaunchActivity方法中执行了两个比较关键的步骤,一个是performLaunchActivity(),另一个是handleResumeActivity()。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
//创建Activity
Activity activity = null;
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);
}
try {
//创建Application
Application app=r.packageInfo.makeApplication(false,mInstrumentation);//创建Application,并将contextImp与Activity相关联
if (activity != null) {
...
// 将contextImp与Window关联相关联
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
...
activity.mCalled = false;
mInstrumentation.callActivityOnCreate(activity, r.state);//调用Activity的OnCreate方法
...
}
...
}
...
}
在performLaunchActivity通过查找packageInfo以及反射机制的ClassLoader构建了一个activity,其中不得不提Instrumentation类,该类是一个辅助类,用于创建 Activity以及application,并通过Instrumentation对应的方法启动Activity的onCreate方法等生命周期方法。
再看一下activity.attach的方法,该方法用于构建一个PhoneWindow并赋值给mWindow
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,
Object lastNonConfigurationInstance,
HashMap<String,Object> lastNonConfigurationChildInstances,
Configuration config) {
......
mWindow = PolicyManager.makeNewWindow(this);
setCallback(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
setSoftInputMode(info.softInputMode);
}
......
setWindowManager(null, mToken, mComponent.flattenToString());
......
}
函数首先调用PolicyManager类的静态成员函数makeNewWindow来创建一个类型为PhoneWindow的应用程序窗口,并且保存在Activity类的成员变量mWindow中。有了这个类型为PhoneWindow的应用程序窗口,函数接下来还会调用它的成员函数setCallback、setSoftInputMode和setWindowManager来设置窗口回调接口、软键盘输入区域的显示模式和本地窗口管理器。
构建完window对象后通过 mInstrumentation.callActivityOnCreate(activity, r.state)执行Activity的OnCreate方法,而onCreate方法执行了对应了setContentView操作,
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
}
即调用了通过Activity中attach方法中构建的phoneWindow的setContentView方法
public void setContentView(int layoutResID) {
if (mContentParent == null) {
installDecor();
} else {
mContentParent.removeAllViews();
}
mLayoutInflater.inflate(layoutResID, mContentParent);
final Callback cb = getCallback();
if (cb != null) {
cb.onContentChanged();
}
}
mLayoutInflater.inflate(layoutResID, mContentParent)用来构建用户自定义的布局,关于inflate的具体加载过程可以查看http://www.atatech.org/articles/37004
installDecor方法用于构造一个DecorView对象DecorView是整个View的根布局,他继承自Framelayout。
private void installDecor() {
if (mDecor == null) {
mDecor = generateDecor();
......
}
if (mContentParent == null) {
mContentParent = generateLayout(mDecor);
//设置标题
mTitleView = (TextView)findViewById(com.android.internal.R.id.title);
if (mTitleView != null) {
if ((getLocalFeatures() & (1 << FEATURE_NO_TITLE)) != 0) {
View titleContainer = findViewById(com.android.internal.R.id.title_container);
if (titleContainer != null) {
titleContainer.setVisibility(View.GONE);
} else {
mTitleView.setVisibility(View.GONE);
}
if (mContentParent instanceof FrameLayout) {
((FrameLayout)mContentParent).setForeground(null);
}
} else {
mTitleView.setText(mTitle);
}
}
}
}
PhoneWindow类的成员函数installDecor就会调用另外一个成员函数generateDecor来创建一个DecorView对象,并且保存在PhoneWindow类的成员变量mDecor中。 PhoneWindow类的成员函数installDecor还会检查前面加载的窗口布局文件是否包含有一个id值为“title”的TextView控件。如果包含有的话,就会将它保存在PhoneWindow类的成员变量mTitleView中,用来描述当前应用程序窗口的标题栏。但是,如果当前应用程序窗口是没有标题栏的,即它的Feature位FEATURE_NO_TITLE的值等于1,那么PhoneWindow类的成员函数installDecor就需要将前面得到的标题栏隐藏起来
这里的构建过程也就是对应了文章http://www.atatech.org/articles/37843第一个图中的Activity 、PhoneWindow以及DecorView。
这里只完成了整个Activity 、Phonewindow以及DecorView,以及自定义布局的初始化操作并没有完整显示View,即通过setContentView()方法并没有显示出任何东西来,而仅仅是将Phonewindow->mDecor->mContentParent->(customer layout)一个这样的树状结构给搭建好了而已。而View的展示是在handleResumeActivity完成的。
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
boolean reallyResume) {
...
//通过 mInstrumentation.callActivityOnResume执行Activity自己的Resume方法
ActivityClientRecord r = performResumeActivity(token, clearHide); if (r != null) {
final Activity a = r.activity;
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();//获取前面设置的window
View decor = r.window.getDecorView();//获取前面设置的DecorView
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
...
}
...
}
}
handleResumeActivity ()方法是通过Instrumentation调用Activity的onResume()方法。
下面的wm.addView()方法非常关键,wm是上面a.getWindowManager()获取到的,a是Activity,getWindowManager()就是返回它的mWindowManger对象,而这个对象是WindowManagerImpl,它的内部方法大部分是代理的WindowManagerGlobal.
然而,这个WindowManger的addView()是干了什么呢?
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
...
ViewRootImpl root;
View panelParentView = null;
...
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
}
// do this last because it fires off messages to start doing things
try {
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
...
throw e;
}
}
从上面的代码可以看出,addView方法中,new了一个ViewRootImpl对象,然后调用ViewRootImpl.setView()方法。
android.view.ViewRootImpl.setView()
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
...
// Schedule the first layout -before- adding to the window
// manager, to make sure we do the relayout before receiving
// any other events from the system.
requestLayout();
...
view.assignParent(this);
...
}
}
}
并执行requestLayout(),接着就可以执行http://www.atatech.org/articles/37843中提到的measure,layout,draw三步操作了
最后通过r.activity.makeVisible()方法将整个Acitivty设置为可见状态
本文源码均来自开源社区:https://github.com/android/platform_frameworks_base