安卓系统启动流程解析
来源:互联网 发布:js获取服务器ip和端口 编辑:程序博客网 时间:2024/06/06 00:40
一直以来一直想有深入研究源码的想法,最近一段时间工作比较少,得以时间研究,有点心得就给大家分享,今天给大家带来的是安卓系统最开始的
话不多说 首先放图
下面来详解这张图
从系统的角度上来讲,Android系统的启动过程可以分为 bootloader 引导,装载和启动 linux内核 启动Android系统
BootLoader
bootloader 相当于电脑上的Bios 他的主要作用就是初始化基本的硬件设备,建立内存空间映射, 为装载linux内核准备好运行环境,当linux内核加载完毕之后,bootloder就会从内存中清除
对于FastBoot和Recover估计好多童鞋都不理解,fastboot是Android设计的一套通过usb来更新手机分区的映像协议,不过大部分厂商都搞掉了 google的nexus 上应该有的
Recovery模式是Android特有的升级系统,通过这个可以进行手机恢复出厂设置,或执行OTA,补丁和固件升级,实质是启动了一个文本模式的Linux。
bootloader启动后会向内存中装载boot.img镜像文件,这个镜像文件存放的是linux内核和一个根文件系统,linux内核进行初始化之后,装载完文件系统,就启动了init进程
Init进程
init进程是Linux创建的第一个进程,init进程会解析linux的脚本文件init.rc,根据这个文件的内容 init进程会装载Android的文件系统,创建系统目录,初始化属性系统,启动Android系统的重要的守护进程等,如上图,
下面简单的介绍一个下init进程fork出的几个重要的进程:
Zygote进程: 当init进程初始化结束的时候,会启动Zygote进程,看上图可以看出来 zygote进程扶着fork出应用进程,是所有进程的父进程,Zygote进程初始化的时候会创建Dalivik虚拟机,预装载系统的资源文件和java类,所有从Zygote进程fork出的用户进程将继承和共享这些资源,不用浪费时间重新加载(看到这里是不是感觉突然明白了什么?)干完这些之后,Zygote进程也将变为守护进程,负责响应启动APK应用的启动请求。
SystemServer进程:SystemServer进程是Zygote进程fork出的第一个进程,也是整个Android系统的核心进程,在SystemServer主要运行的是Binder服务,SystemServer首要启动本地服务 SensorService 接着启动 ActivityManagerService,WindowsManagerService,PackgeManagerService等在内的所有java服务。
MediaServer进程:也是由init进程启动,他包含了一些多媒体相关的本地Binder服务,包括CameraService,AudioFilingerService ,和AudioPolicyService。
当SystemServer加载完所有Java服务后最后会调用ActivityManagerService的SystemReady()方法,
// We now tell the activity manager it is okay to run third party // code. It will call back into us once it has gotten to the state // where third party code can really run (but before it has actually // started launching the initial applications), for us to complete our // initialization. mActivityManagerService.systemReady(new Runnable() { @Override public void run() { Slog.i(TAG, "Making services ready"); mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes", e); } Slog.i(TAG, "WebViewFactory preparation"); WebViewFactory.prepareWebViewInSystemServer(); try { startSystemUi(context); } catch (Throwable e) { reportWtf("starting System UI", e); } try { if (mountServiceF != null) mountServiceF.systemReady(); } catch (Throwable e) { reportWtf("making Mount Service ready", e); } try { if (networkScoreF != null) networkScoreF.systemReady(); } catch (Throwable e) { reportWtf("making Network Score Service ready", e); } try { if (networkManagementF != null) networkManagementF.systemReady(); } catch (Throwable e) { reportWtf("making Network Managment Service ready", e); } try { if (networkStatsF != null) networkStatsF.systemReady(); } catch (Throwable e) { reportWtf("making Network Stats Service ready", e); } try { if (networkPolicyF != null) networkPolicyF.systemReady(); } catch (Throwable e) { reportWtf("making Network Policy Service ready", e); } try { if (connectivityF != null) connectivityF.systemReady(); } catch (Throwable e) { reportWtf("making Connectivity Service ready", e); } try { if (audioServiceF != null) audioServiceF.systemReady(); } catch (Throwable e) { reportWtf("Notifying AudioService running", e); } Watchdog.getInstance().start(); // It is now okay to let the various system services start their // third party code... mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); try { if (wallpaperF != null) wallpaperF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying WallpaperService running", e); } try { if (immF != null) immF.systemRunning(statusBarF); } catch (Throwable e) { reportWtf("Notifying InputMethodService running", e); } try { if (locationF != null) locationF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying Location Service running", e); } try { if (countryDetectorF != null) countryDetectorF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying CountryDetectorService running", e); } try { if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying NetworkTimeService running", e); } try { if (commonTimeMgmtServiceF != null) { commonTimeMgmtServiceF.systemRunning(); } } catch (Throwable e) { reportWtf("Notifying CommonTimeManagementService running", e); } try { if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying TextServicesManagerService running", e); } try { if (atlasF != null) atlasF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying AssetAtlasService running", e); } try { // TODO(BT) Pass parameter to input manager if (inputManagerF != null) inputManagerF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying InputManagerService running", e); } try { if (telephonyRegistryF != null) telephonyRegistryF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying TelephonyRegistry running", e); } try { if (mediaRouterF != null) mediaRouterF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying MediaRouterService running", e); } try { if (mmsServiceF != null) mmsServiceF.systemRunning(); } catch (Throwable e) { reportWtf("Notifying MmsService running", e); } } });从上面的注释我们可以得出他是去打开lancher 具体的代码在这里
public void systemReady(final Runnable goingCallback) { synchronized(this) { if (mSystemReady) { // If we're done calling all the receivers, run the next "boot phase" passed in // by the SystemServer if (goingCallback != null) { goingCallback.run(); } return; } // Make sure we have the current profile info, since it is needed for // security checks. updateCurrentProfileIdsLocked(); .................................... 此处省略大量代码 // Start up initial activity. mBooting = true; <strong><u><span style="color:#000066;background-color: rgb(204, 204, 204);">startHomeActivityLocked(mCurrentUserId, "systemReady");</span></u></strong> try { if (AppGlobals.getPackageManager().hasSystemUidErrors()) { Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your" + " data partition or your device will be unstable."); mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget(); } } catch (RemoteException e) { } if (!Build.isFingerprintConsistent()) { Slog.e(TAG, "Build fingerprint is not consistent, warning user"); mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget(); } long ident = Binder.clearCallingIdentity(); try { Intent intent = new Intent(Intent.ACTION_USER_STARTED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); broadcastIntentLocked(null, null, intent, null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException { } }, 0, null, null, INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); } catch (Throwable t) { Slog.wtf(TAG, "Failed sending first user broadcasts", t); } finally { Binder.restoreCallingIdentity(ident); } mStackSupervisor.resumeTopActivitiesLocked(); sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); } }这个里面最重要的就是标出的那一行,调用的方法是源码是在这里
boolean startHomeActivityLocked(int userId, String reason) { if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) { // We are running in factory test mode, but unable to find // the factory test app, so just sit around displaying the // error message and don't try to start anything. return false; } <strong style="background-color: rgb(192, 192, 192);"> Intent intent = getHomeIntent();</strong> ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); if (aInfo != null) { intent.setComponent(new ComponentName( aInfo.applicationInfo.packageName, aInfo.name)); // Don't do this if the home app is currently being // instrumented. aInfo = new ActivityInfo(aInfo); aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); ProcessRecord app = getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid, true); if (app == null || app.instrumentationClass == null) { intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); mStackSupervisor.startHomeActivity(intent, aInfo, reason); } } return true; }看到这里大家明白了吧,这个getHomeIntent() 就是打开launcher应用的Inent
Intent getHomeIntent() { Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); intent.setComponent(mTopComponent); if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { intent.addCategory(Intent.CATEGORY_HOME); } return intent; }
其实在上一段代码中还要去PackageManager去取一下所有类型为ACTION_MAIN的intent 然后才开的Launcher。
大致的流程就这些,中间有些部分会再以后的博文里接着分析,如果看到有什么错误的地方,都可以在下面评论中说出。希望我们共同进步!
- 安卓系统启动流程解析
- 安卓系统启动流程
- 安卓系统启动过程
- 安卓框架层(系统启动流程)(1)系统架构
- 系统启动流程
- 系统启动流程
- 系统启动流程
- 系统启动流程
- Android系统启动流程(一)解析init进程启动过程
- Android系统启动流程(二)解析Zygote进程启动过程
- Android系统启动流程(三)解析SyetemServer进程启动过程
- Android系统启动流程(一)解析init进程启动过程
- 安卓启动流程
- 安卓启动流程
- 安卓启动流程
- 安卓开机流程
- 安卓启动流程
- 安卓编译流程
- 缓冲区溢出攻击
- 超级封装让你的项目搭建事半功倍-单Activity多Fragment模式
- 在线实时大数据平台Storm并行度试验
- 你和高级工程师的差距(摘取)
- Python练习100例-22
- 安卓系统启动流程解析
- iTunes Connect 基本使用说明
- 9w6:第九周程序填空题2
- loadrunner脚本,从FTP服务器上上传和下载文件
- jQuery prop() 方法
- InvokeRequired和Invoke
- PHP安全编程之阻止文件名被操纵
- VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径
- 设置断点追踪entry_point