Android沒有單獨(dú)的啟動(dòng)應(yīng)用進(jìn)程擒抛,而是在啟動(dòng)四大組件的時(shí)候校驗(yàn)是否啟動(dòng)進(jìn)程蔬充,如果沒有啟動(dòng)進(jìn)程那么AMS會(huì)通過socket通信請求zygote進(jìn)程去fork應(yīng)用進(jìn)程
一羽莺、創(chuàng)建應(yīng)用進(jìn)程
1、會(huì)將“android.app.ActivityThread”作為參數(shù)傳給zygote進(jìn)程
2猬错、zygote進(jìn)程socket接收到消息到會(huì)執(zhí)行runOnce()函數(shù),然后通過fork機(jī)制創(chuàng)建進(jìn)程
if (pid == 0) {
// in child
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
return true;
} else {
// in parent...pid of < 0 means failure
return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
3茸歧、執(zhí)行handleChildProc()方法會(huì)調(diào)用到zygoteInit()
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
nativeZygoteInit();
applicationInit(targetSdkVersion, argv, classLoader);
}
4倦炒、nativeZygoteInit()會(huì)啟動(dòng)Binder通信
5、applicationInit(targetSdkVersion, argv, classLoader); 會(huì)反射調(diào)用“android.app.ActivityThread”也就是最開始從AMS傳過來的字符串软瞎,然后調(diào)用ActivityThread的main方法
二逢唤、啟動(dòng)binder進(jìn)程
1、開啟binder驅(qū)動(dòng) open
2涤浇、內(nèi)存映射 mmap
3鳖藕、將線程加入binder線程池
4、循環(huán)等待消息
三只锭、應(yīng)用進(jìn)程初始化工作
ActivityThread的main方法
public static void main(String[] args) {
Looper.prepareMainLooper();
//在attach方法中會(huì)完成Application對象的初始化著恩,然后調(diào)用Application的onCreate()方法
ActivityThread thread = new ActivityThread();#
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}
1、首先會(huì)創(chuàng)建主線程的Looper(主線程的Looper和子線程的Looper區(qū)別是主線程Looper不能退出)
2蜻展、創(chuàng)建ActivityThread對象(這個(gè)對象就單純的是一個(gè)對象喉誊,不是一個(gè)線程)
3、attach方法會(huì)通知會(huì)通知AMS纵顾、反射創(chuàng)建Context綁定Application的Context伍茄,
4、循環(huán)等待消息
四施逾、通知AMS應(yīng)用進(jìn)程創(chuàng)建成功
ActivityThread的attach方法:
private void attach(boolean system) {
...
if (!system) {
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}else{
...
}
}
}
ActivityManagerService中的方法:
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
AMS中的方法敷矫,主要功能有以下兩步
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
...
主要用于創(chuàng)建Application,用調(diào)用onCreate方法
thread.bindApplication(...);
...
主要用于創(chuàng)建Activity
if (mStackSupervisor.attachApplicationLocked(app)) {
...
}
}
在每個(gè)ActivityThread(APP)被創(chuàng)建的時(shí)候汉额, 都需要向ActivityManagerService綁定(或者說是向遠(yuǎn)程服務(wù)AMS注冊自己)曹仗,用于AMS管理ActivityThread中的所有四大組件的生命周期。
五闷愤、應(yīng)用層創(chuàng)建Context
AMS調(diào)用bindApplication()后會(huì)調(diào)用到ActivityThread的makeApplication()
LoadedApk中的方法整葡,用于創(chuàng)建Application
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
如果存在Application的實(shí)例,則直接返回讥脐,這也說明Application是個(gè)單例
if (mApplication != null) {
return mApplication;
}
Application app = null;
...這里通過反射初始化Application
if (instrumentation != null) {
try {
調(diào)用Application的onCreate方法
instrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
}
}
return app;
}
六遭居、創(chuàng)建Activity
調(diào)用ApplicationThread的scheduleLaunchActivity用于啟動(dòng)一個(gè)Activity
app.thread.scheduleLaunchActivity(...);
參考
https://blog.csdn.net/itachi85/article/details/64123035
https://blog.csdn.net/itachi85/article/details/64243223?depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1&utm_source=distribute.pc_relevant_t0.none-task-blog-OPENSEARCH-1
https://blog.csdn.net/hzwailll/article/details/85339714