众所周知,Android 中的用户进程是由 Zygote 孵化的。通知Zygote fork()进程是在 ActivityManagerService 中,同时 Zygote 与 ActivityManagerService是用过 socket 通信的。
详见Zygote进程及其孵化子进程
当子进程fork 后,会调用ActivityThread.main(String[ ]),这部分是在子进程,即 app 进程运行的;
//android.app.ActivityThread
public static void main(String[] args){
...
//现在还不知道这个用户进程的名字
Process.setArgVo("<pre-initialized>");
//这个就是传说中的主线程了,开启了一个 looper
Looper.prepareMainLooper();
//构造函数比较简单,只是单纯的创造了mResourceManager=ResourceManager.getInstance()
ActivityThread thread = new ActivityThread();
//system=false
thread.attach(false);
if(sMainThreadHandler == null){
//这个就是 H 类,用以处理启动 activity 等消息的 Handler
sMainThreadHandler = thread.getHandler();
}
Lopper.loop();
}
private void attach(boolean system){
//这东西是整个应用的单例,并且是 static 的,经常作为黑科技的 hook 点
sCurrentActivityThread = this;
mSystemThread = system;//这里是 false,表示是普通的进程
if(!system){
//与 AMS binder 通信,执行system_server中 AMS 的attachApplication()
final IActivityManager mgr = ActivityManagerNative.getDefault();
//mAppThread 是 ApplicationThread 类,包含很多可以和mH 通讯的方法,是进行 Binder 通信的
mrg.attachApplication(mAppThread);
...
}else{
//系统应用,不关心
...
}
}
转到 AMS:
//AMS
public final void attachApplication(IApplicationThread thread){
//Binder.getCallingPid(),获得调用该方法的进程 id,在本例中就是这个用户 app
int callingPid = Binder.getCallingPid();
attachApplicationLocked(thread, callingPid);
}
private final boolean attachApplicationLocked(IApplicationThread thread, int pid){
// 获取进程相关的信息
ProcessRecord app = mPidSelfLocked.get(pid);
...
//binder 通信,又回到了用户 app
//通过AMS 获得用户进程相关信息,并且恰当的返回给用户进程
thread.bindApplication(...);
...
//这里会启动 app 的 launcher Activity
if(mStackSupervisor.attachApplicationLocker(app)){
...
}
}
//bindApplication(...)@ActivityThread$ApplicationThread
public final void bindApplication(...N 多参数,与当前进程相关){
//获得该进程相关的 PackageInfo
IPackageManager pm = getPackageManager();
android.content.pm.PackageInfo pi = pm.getPackageInfo(appInfo.packageName,0,UserHandler,myUserId);
AppBindData data = new AppBindData();
{通过AMS返回的数据组装用户进程需要的 AppBindData}
..sendMessage(H.BINDER_APPLICATION,data);
}
mH分发,调用handleBinderApplication(AppBindData)@ActivityThread
``
private void handleBindApplication(AppBindData data){
// 终于正确设置了进程名
android.ddm.DdmHandleAppName.setAppName(data.processName,UserHandle.myUserId());
final ContextImpl appContext = ContextImpl.createAppContext(this,data.info);
...
ContextImpl instrContext = Context.createAppContext(this, pi);
//创建关键管家类 Instrumentation
java.lang.ClassLoader cl=instrContext.getClassLoader();
mInstrumentation = (Instrumentation)cl.loadClass(data.instrumentionName.getClassName()).newInstance();
mInstrumentation.init(...);
}
...
//里面通过反射创建 Application,并且创建一个 ContextImpl 绑定到 app 上
Application app = data.info.makeApplication(data.restrictedBackupMpde,null)
...
//调用onCreate()@Application
mInstrumentation.callApplicationOnCreate(app);
//以上,在用户进程完成了当前进程相关的信息的查询以及绑定,并且生成了上下文 Instrumentation与Application两个重要的类。
//接下里另外一条线进行 Launcher Activity的启动了
//attachApplicationLocker(AppliationThread)@ActivityStackSupervisor
boolean attachApplication(ProcessRecord app){
ActivityRecord hr = stack.topRunningActivityLocaked(null);
//关键
realStartActivityLocked(hr, app, true, true);
}
final boolean readlStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig){
//只看关键一句
//app.thread是用户进程 ApplicationThread binder对象
app.thread.scheduleLaunchActivity(...);
}
又回到了用户进程,scheduleLanchActivity()@ActivityThread$ApplicationThread
public final void scheduleLaunchActivity(...){
ActivityClientRecord r = new ActivityClientRecord();
{组装 ActivityClientRecord 信息}
sendMessage(H.LAUNCH_ACTIVITY,r);
}
H
{
handleLaunchaerActivity(ActivityClientRecord r,null);
}
//ActivityThread
private void handleLaunchActivity(ActivityClientRecord r,Intent customIntent){
// 生成 Activity 并且初始化
Activity a = performLaunchActivity(r, customIntent);
//调用onRestart() ,onStart()与 onResume()
handleResumeActivity(...);
}
private Activity performLaunchActivity(ActivityClientRecord r,Intent customIntent){
//反射生成 Activity
Activity activity=mInstrumentation.newActivity(clmcomponent.getClassName(),r.intent);
//单例,即App 的 Application
Application App=r.packageInfo.makeAppliction(falsemmInstrumentation);
//实例化一个 ContextImpl
Context appContext = createBaseContextForActivity(r, activity);
//绑定到 activity,也可以看到 Instrumentation 是共享的
//调用 attach(Context)@activity
activity.attach(appContext,this,getInstrumentation()...);
//onCreate()@Activity生命周期
mInstrumentation.callActivityOnCreate();
//onPostCreate()@Activity生命周期
//mInstrumentation.callActivityOnPostCreate();
}
网友评论