android从开机到Application加载全过程

Android系统其实是基于Linux系统的。当我们长按下电源启动手机时,引导芯片开始从固化在ROM里的预设代码开始执行。加载引导程序Bootloader到RAM,然后执行。BootLoader是在Linux操作系统开始运行前的一个小程序,它的主要作用是把系统OS拉起来并运行。在系统内核启动后,便会去设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc文件,并启动init进程。
init进程

在Linux中,第一个启动的进程就是init进程。然后后面所有的进程都是由init进程直接或者是间接创建出来的。init进程在启动后会初始化和启动属性服务,并且创建出一个名字很有意思的新的进程,它便是Zygote进程。

Zygote进程

Zygote进程也有人直接用中文叫“受精卵进程”。一个有意思的名字,使人很容易记住和想知道它是何方神圣。当然Android攻城狮命名不是随便定的,因为Zygote进程启动后,Android为了实现实现资源共用和更快的启动速度,通过Zygote进程直接去创建出子进程,也就是Android中所有app都是基于Zygote上的,当Zygote初始化完成之后,会创建JavaVM并为JavaVM注册JNI,创建服务端Socket,启动它第一个子进程SystemServer。

SystemServer进程

SystemServer进程作用是启动Binder线程池和SystemServiceManager,并且启动各种重要的系统服务,如:ActivityManagerService、PowerManagerService、PackageManagerService、WindowManagerService,等等80多个系统服务。

ActivityManagerService进程

ActivityManagerService从字面意思上看是管理Activity的,但其实四大组件都归它管,ActivityManagerService所在进程启动后,会启动系统桌面Launcher。

Launcher

Launcher是一个特殊的app,它主要作用是用来显示widget和显示已装应用的快捷图标到界面上。当我们点击Launcher上的快捷图标后,就能启动app。
Android中的每一个App,都是独立运行在自己的进程中的。上面提到,当点击Launcher上的快捷图标后就会启动App。为什么点击快捷图标后就会启动App?因为Launcher源码告诉我们,它内部调用了startActivity:
因为Launcher类是继承于Activity的,所以上面调用的startActivity()就是Activity.java里的startActivity()方法。调了startActivity()方法后面会判断app的进程是否存在,若不存在,则会先建立app的进程。其步骤大概是这样:通过ActivityManagerService请求服务端Socket,服务端Socket再去请求Zygoto进程,然后Zygoto进程就会fork自身来创建app的进程。当app进程创建时,它的主线程也会被创建,此时app的第一个类ActivityThread的main()方法就会被调用,main()方法里头就会进行相关的初始化。这也是我们常说的Android中app第一个入口代码是ActivityThread.main()。

可能看到,startActivity()方法最后是调用了startActivityForResult()方法,方法内做了一个mParent变量是否为空的判断,mParent其实也是一个Activity,关键代码2的中mParent.startActivityFromChild()方法里头也是调用了mInstrumentation.execStartActivity()方法,所以我们继续看关键代码1的execStartActivity()方法:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
……
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
// 关键代码
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
getDefault()方法中通过一个全局变量gDefault的get()方法返回对象出去,而gDefault变量中通过ServiceManager.getService(“activity”)初始化一个IBinder对象。它是通过Binder实现进程间通信的。很明显这里是用一个“activity”的key来获得对象,那么此key又在何处set,答案就在ActivityManagerService中,请看源码:

ActivityManagerService.java

public void setSystemProcess() {
try {
// 关键代码
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService(“meminfo”, new MemBinder(this));
ServiceManager.addService(“gfxinfo”, new GraphicsBinder(this));
ServiceManager.addService(“dbinfo”, new DbBinder(this));
……
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(“Unable to find android system package”, e);
}
}
当Activity的进程不存在时,就会调用关键代码2的ActivityManagerService的startProcessLocked()方法创建进程,我们本次是从Launcher启动的Activity的,进程当然是不存在,所以就会执行mService.startProcessLocked()来新建进程,我们来看看具体代码:

ActivityManagerService.java

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
……
if (app == null) {
checkTime(startTime, “startProcess: creating new process record”);
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
if (app == null) {
Slog.w(TAG, “Failed making new process record for "
+ processName + “/” + info.uid + " isolated=” + isolated);
return null;
}
app.crashHandler = crashHandler;
mProcessNames.put(processName, app.uid, app);
if (isolated) {
mIsolatedProcesses.put(app.uid, app);
}
checkTime(startTime, “startProcess: done creating new process record”);
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, “startProcess: added package to existing proc”);
}
……
// 关键代码
startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, “startProcess: done starting proc!”);
return (app.pid != 0) ? app : null;
}

private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
……
try {
……
// 关键代码
if (entryPoint == null) entryPoint = “android.app.ActivityThread”;
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
……
} catch (RuntimeException e) {
……
}
}
可以看出,Process.start()方法传入的第一个参数是ActivityThread类名,我们知道ActivityThread类是app的入口类,再继续往下看
Process.java

public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] zygoteArgs) {
try {
// 关键代码
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
“Starting VM process through Zygote failed”);
throw new RuntimeException(
“Starting VM process through Zygote failed”, ex);
}
请看关键代码行,startViaZygote()方法名已经很明显了,就是开始通过Zygote启动进程,继续看:

private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
ArrayList argsForZygote = new ArrayList();
……
// 关键代码
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
看源码难免会让人感到乏味和无趣,但主要记住关键点其实就足够了:

Android系统启动后第一个进程是init进程,其次是Zygote进程
Android里所有的app都是运行在自己单独的进程里,其进程是通过Zygote进程fork自身来创建出来的
Android中所有app的入口都是ActivityThread.main()方法

ActivityThread类方法Main()中
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread, startSeq);//加载Application
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值