[Android]Android系统启动流程源码分析
以下内容为原创,欢迎转载,转载请注明
来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5013863.html
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
: -
注意,这里传入的参数是forkRuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
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);// 初始化主线程LooperLooper.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); // ...}
到此为止,SystemServer
start完毕,并且启动了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 Activity启动和退出过程中onResume()方法的回调
- andorid跳过系统API获取以太网IP,网关,DNS,MAC的方法
- 【Android】关联source code的方法
- [转]NDK中log输出方法
- Android应用程序设置系统时间的方法
- Android官方使低版本系统(2.1)支持ActionBar的方法