[Android]Android系统启动流程源码分析
2016-09-17 19:20
701 查看
Android系统启动流程源码分析
首先我们知道,Android是基于
Linux的,当
Linux内核加载完成时就会自动启动一个
init的进程。
又因为我们每当我们启动一个App时,就会生成一个新的
dalvik实例,并处于一个新的进程(当然一个App也可能是多进程的)。
当我们打开第一个App的时候,就会通过
init进程fork出一个
zygote进程。之后打开新的App的时候都会
fork之前的
zygote进程。
当
fork一个
zygote进程时,会进入
com.android.internal.os.ZygoteInit的
main方法进行初始化操作:
预加载资源
// ... preloadClasses(); preloadResources(); preloadOpenGL(); preloadSharedLibraries(); preloadTextResources(); // Ask the WebViewFactory to do any initialization that must run in the zygote process, // for memory sharing purposes. WebViewFactory.prepareWebViewInZygote(); // ...
从第一个
zygote进程
fork出
SystemServer进程,这个进程提供各种
ManagerService。
startSystemServer(abiList, socketName); private static boolean startSystemServer(String abiList, String socketName) throws MethodAndArgsCaller, RuntimeException { int pid; // ... String args[] = { "--setuid=1000", "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007", "--capabilities=" + capabilities + "," + capabilities, "--nice-name=system_server", "--runtime-args", "com.android.server.SystemServer", }; /* Request to fork the system server process */ pid = Zygote.forkSystemServer( parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, null, parsedArgs.permittedCapabilities, parsedArgs.effectiveCapabilities); // ... }
Fork完
SystemServer进程之后,继续接下来在
handleSystemServerProcess方法中传入参数到
SystemServer:
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
注意,这里传入的参数是fork
SystemServer进程后剩下的参数(
parsedArgs.remainingArgs),其实只剩下了
com.android.server.SystemServer这个参数了。
接下来继续调用
applicationInit,传入参数:
private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { final Arguments args; // ... args = new Arguments(argv); // ... }
解析成
Arguments后,得到了一个
startClass对象,这个
startClass其实就是刚刚的那个
com.android.server.SystemServer。
接下来,继续调用
invokeStaticMain
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class<?> cl; // ... cl = Class.forName(className, true, classLoader); // ... m = cl.getMethod("main", new Class[] { String[].class }); // ... throw new ZygoteInit.MethodAndArgsCaller(m, argv); }
就是调用通过反射得到
com.android.server.SystemServer(也就是上面的
startClass)的
main(argv[])方法,然后手动抛一个携带了这个
main(argv[])方法的
MethodAndArgsCaller异常,但是这个异常是在
ZygoteInit.main()方法中被catch,然后去调用它的
run()方法,当然这个
run()方法中会再去通过反射调用携带的
main()方法(这个绕法真是有点坑爹--。):
public static class MethodAndArgsCaller extends Exception implements Runnable { // ... public void run() { // ... mMethod.invoke(null, new Object[] { mArgs }); // ... } // ... }
绕了这么一大圈,终于通过
MethodAndArgsCaller调用
SystemServer的
main()方法了,代码很简单,直接
new了之后
run:
new SystemServer().run();
接着,我们看
SystemServer的
run方法:
// ... (省略初始化当前的language、locale、country、指纹、用户等信息的初始化准备工作) // 设置当前进程设置优先级为THREAD_PRIORITY_FOREGROUND(-2) android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); // 初始化主线程Looper Looper.prepareMainLooper(); // ... // 启动消息循环 Looper.loop()
然后调用
createSystemContext()方法创建初始化
system context,这个待会再展开。
创建
SystemServiceManager:
mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
使用
SystemServiceManager去通过以下方法创建启动各个
Service:
startBootstrapServices():
com.android.server.pm.Installer:提供安装、卸载App等服务
com.android.server.am.ActivityServiceManager:提供Activity等组件的管理的服务,这个比较复杂暂且再挖个坑。
com.android.server.power.PowerManagerService:电源管理的服务。
com.android.server.lights.LightsService:LED管理和背光显示的服务。
com.android.server.display.DisplayManagerService:提供显示的生命周期管理,根据物理显示设备当前的情况决定显示配置,在状态改变时发送通知给系统和应用等服务。
com.android.server.pm.PackageManagerService:管理所有的
.apk。
com.android.server.pm.UserManagerService:提供用户相关服务。
通过
startSensorService()本地方法启动Sensor服务。
startCoreServices();
com.android.server.BatteryService:电量服务,需要
LightService。
com.android.server.usage.UsageStatsService:提供收集统计应用程序数据使用状态的服务。
com.android.server.webkit.WebViewUpdateService:私有的服务(@hide),用于
WebView的更新。
startOtherServices();
com.android.server.accounts.AccountManagerService:提供所有账号、密码、认证管理等等的服务。
com.android.server.content.ContentService:用户数据同步的服务。
com.android.server.VibratorService:震动服务。
IAlarmManager:提醒服务。
android.os.storage.IMountService:存储管理服务。
com.android.server.NetworkManagementService:系统网络连接管理服务。
com.android.server.net.NetworkStatsService:收集统计详细的网络数据服务。
com.android.server.net.NetworkPolicyManagerService:提供低网络策略规则管理服务。
com.android.server.ConnectivityService:提供数据连接服务。
com.android.server.NetworkScoreService:
android.net.NetworkScoreManager的备份服务。
com.android.server.NsdService:网络发现服务(Network Service Discovery Service)。
com.android.server.wm.WindowManagerService:窗口管理服务。
com.android.server.usb.UsbService:USB服务。
com.android.server.SerialService:串口服务。
com.android.server.NetworkTimeUpdateService:网络时间同步服务。
com.android.server.CommonTimeManagementService:管理本地常见的时间配置的服务,当网络配置变化时会重新配置本地服务。
com.android.server.input.InputManagerService:事件传递分发服务。
com.android.server.TelephonyRegistry:提供电话注册管理的服务。
com.android.server.ConsumerIrService:远程控制服务。
com.android.server.audio.AudioService:音量、铃声、声道等管理服务。
com.android.server.MmsServiceBroker:
MmsService的代理,因为
MmsService运行在电话进程中,可能随时crash,它会通过一个
connection与
MmsService建立一个桥梁,
MmsService实现了公开的
SMS/MMS的API。
TelecomLoaderService
CameraService
AlarmManagerService
BluetoothService
还有其它很多很多Service,这方法竟然有近1000行……
在
startOtherServices()方法的最后:
mActivityManagerService.systemReady(new Runnable() { @Override public void run() { // 下面仍然是各种Service的启动... } }
调用这个方法用来告诉
ActivityManagerService,此时可以运行第三方的代码了(注意:这里的Home界面、Launcher等内置的App也算是第三方的App)。
public void systemReady(final Runnable goingCallback) { // ... if (mSystemReady) { // 回调到SystemServer,继续启动各种Service if (goingCallback != null) { goingCallback.run(); } return; } // ... ResolveInfo ri = mContext.getPackageManager().resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS); // ... ActivityInfo ai = ri.activityInfo; ApplicationInfo app = ai.applicationInfo; // ...从PackageManager中获取要打开的HomeActivity mTopComponent = new ComponentName(app.packageName, ai.name); // ... // 启动第一个Home界面 startHomeActivityLocked(mCurrentUserId, "systemReady"); // ... // 广播通知启动完成 broadcastIntentLocked(/*...*/, mCurrentUserId); broadcastIntentLocked(/*...*/, UserHandle.USER_ALL); // ... }
启动Home界面的
startHomeActivityLocked方法,调用
mStackSupervisor启动
HomeActivity:
boolean startHomeActivityLocked(int userId, String reason) { // ... Intent intent = getHomeIntent(); // ... intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); mStackSupervisor.startHomeActivity(intent, aInfo, reason); // ... } Intent getHomeIntent() { Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); // 设置前面获取到的mTopComponent intent.setComponent(mTopComponent); // ... intent.addCategory(Intent.CATEGORY_HOME); // ... }
到此为止,
SystemServerstart完毕,并且启动了Home界面。
然后我们再回过头去看看在我们前面创建系统级的
Context(
createSystemContext)的时候做了什么:
ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
首先调用了
ActivityThread的静态方法
systemMain():
public static ActivityThread systemMain() { // ... ActivityThread thread = new ActivityThread(); thread.attach(true); return thread; }
创建一个
ActivityThread,然后调用它的
attach()方法:
thread.attach(true); private void attach(boolean system) { if (!system) { // ... }else{ // ... mInstrumentation = new Instrumentation(); ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo); mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); // ... } }
参数
system表示,是否是系统级的线程,现在我们是启动整个Android系统,显然当前传入的参数为
true。所以进入else,首先,创建一个
Instrumentation,
Instrumentation是什么?暂时先挖个坑。接着通过
System Context创建一个
ContextImpl,然后使用它的
LoadedApk::makeApplication方法来创建整个应用的
Application对象,然后调用
Application的
onCreate方法。
然后看下
LoadedApk::makeApplication方法的实现:
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { // 只有第一次调用makeApplication才会往下执行 if (mApplication != null) { return mApplication; } // 初始化系统的Application,所以appClass是"android.app.Application" String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; } // ... ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); // ... }
创建
appContext,然后通过
Instrumentation生成
Application对象,并给
appContext设置外部引用
相关文章推荐
- Android系统启动流程源码分析
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- [Android]Android系统启动流程源码分析
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- Android系统启动流程源码分析
- 【源码分析】Android系统启动流程.
- Android 5.0 Camera系统源码分析(1):CameraService启动流程
- android开发之源码级分析(系统启动流程 & Handler消息机制 & AsyncTask机制)
- 源码级分析Android系统启动流程
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
- Android中ICS4.0源码Launcher启动流程分析【android源码Launcher系列一】
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
- Android中ICS4.0源码Launcher启动流程分析【android源码Launcher系列一】
- Android中ICS4.0源码Launcher启动流程分析【android源码Launcher系列一】
- Android源码分析---系统开机流程
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
- Android系统默认Home应用程序(Launcher)的启动过程源码分析
- android系统启动流程之init.rc详细分析笔记
- Android系统默认Home应用程序(Launcher)的启动过程源码分析