android7.x Launcher3源码解析(1)---启动流程
2017-04-07 16:10
435 查看
Launcher系列目录:
一、android7.x Launcher3源码解析(1)—启动流程
二、android7.x Launcher3源码解析(2)—框架结构
三、android7.x Launcher3源码解析(3)—workspace和allapps加载流程
Launcher是安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher。Launcher是安卓系统中的主要程序组件之一,安卓系统中如果没有Launcher就无法启动安卓桌面,Launcher出错的时候,安卓系统会出现“进程 com.android.launcher 意外停止”的提示窗口。这时需要重新启动Launcher。 —— 百度百科
下面盗用网上的一张启动流程图:
Android系统是运作在linux内核上的,为了启动并运行整个android系统,google实现了android系统的init进程。
Android init进程的入口文件在system/core/init/init.cpp中。
init进程主要做了三件事:
1. 创建一些文件夹并挂载设备
2. 初始化和启动属性服务
3. 解析init.rc配置文件并启动zygote进程
关于init进程,想要详细了解的同学可以参考博客Android7.0 init进程源码分析
Zygote进程共做了如下几件事:
1. 创建AppRuntime并调用其start方法,启动Zygote进程。
2. 创建JavaVM并为JavaVM注册JNI.
3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
4. 通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。
5. 启动SystemServer进程。
1.启动Binder线程池,这样就可以与其他进程进行通信。
2.创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理。
3.启动各种系统服务。
分析一下SystemServer.java的代码(原谅我只分析java代码,cpp代码好多年不用了)
进入run方法,发现里面做了很多事情
代码还算清晰,首先初始化一些时间、local、binder的最大进程数,启动Binder线程池啥的。
下来就是加载android_servers库,
紧接着就是创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
接下来就是启动系统的各种服务
上图可见,服务分为3类,
1、BootstrapServices为引导服务,启动的service包括:
Installer 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务
ActivityManagerService 负责四大组件的启动、切换、调度。
PowerManagerService 计算系统中和Power相关的计算,然后决策系统应该如何反应
LightsService 管理和显示背光LED
DisplayManagerService 用来管理所有显示设备
UserManagerService 多用户模式管理
SensorService 为系统提供各种感应器服务
PackageManagerService 用来对apk进行安装、解析、删除、卸载等等操作
2、 CoreServices为核心服务,包括:
BatteryService 管理电池相关的服务
UsageStatsService 收集用户使用每一个APP的频率、使用时常
WebViewUpdateService WebView更新服务
3、OtherServices其他服务,包括很多服务,比如:
CameraService 摄像头相关服务
AlarmManagerService 全局定时器管理服务
InputManagerService 管理输入事件
WindowManagerService 窗口管理服务
VrManagerService VR模式管理服务
BluetoothService 蓝牙管理服务
NotificationManagerService 通知管理服务
DeviceStorageMonitorService 存储相关管理服务
LocationManagerService 定位管理服务
AudioService 音频相关管理服务
创建了一个Intent,并将mTopAction和mTopData传入。mTopAction的值为Intent.ACTION_MAIN,并且如果系统运行模式不是1(这个1是什么意思?)则将intent的Category设置为
而Launcher的AndroidManifest.xml文件里面给Launcher定义的category就是android.intent.category.HOME,
之后,就将含有这个属性的Launcher启动了
至此,Launcher这个app作为一个home桌面就启动出来了。启动之后的界面划分和模块分析下一篇讲解。
一、android7.x Launcher3源码解析(1)—启动流程
二、android7.x Launcher3源码解析(2)—框架结构
三、android7.x Launcher3源码解析(3)—workspace和allapps加载流程
Launcher是安卓系统中的桌面启动器,安卓系统的桌面UI统称为Launcher。Launcher是安卓系统中的主要程序组件之一,安卓系统中如果没有Launcher就无法启动安卓桌面,Launcher出错的时候,安卓系统会出现“进程 com.android.launcher 意外停止”的提示窗口。这时需要重新启动Launcher。 —— 百度百科
下面盗用网上的一张启动流程图:
1、init进程
当Linux内核启动之后,运行的第一个进程是init,这个进程是一个守护进程,它的生命周期贯穿整个linux 内核运行的始终, linux中所有其它的进程的共同始祖均为init进程。Android系统是运作在linux内核上的,为了启动并运行整个android系统,google实现了android系统的init进程。
Android init进程的入口文件在system/core/init/init.cpp中。
init进程主要做了三件事:
1. 创建一些文件夹并挂载设备
2. 初始化和启动属性服务
3. 解析init.rc配置文件并启动zygote进程
关于init进程,想要详细了解的同学可以参考博客Android7.0 init进程源码分析
2、Zygote孵化器
在Android系统中,JavaVM(Java虚拟机)、应用程序进程以及运行系统的关键服务的SystemServer进程都是由Zygote进程来创建的,我们也将它称为孵化器。它通过fock(复制进程)的形式来创建应用程序进程和SystemServer进程,由于Zygote进程在启动时会创建JavaVM,因此通过fock而创建的应用程序进程和SystemServer进程可以在内部获取一个JavaVM的实例拷贝。Zygote进程共做了如下几件事:
1. 创建AppRuntime并调用其start方法,启动Zygote进程。
2. 创建JavaVM并为JavaVM注册JNI.
3. 通过JNI调用ZygoteInit的main函数进入Zygote的Java框架层。
4. 通过registerZygoteSocket函数创建服务端Socket,并通过runSelectLoop函数等待ActivityManagerService的请求来创建新的应用程序进程。
5. 启动SystemServer进程。
3、SystemServer
SyetemServer在启动时做了如下工作:1.启动Binder线程池,这样就可以与其他进程进行通信。
2.创建SystemServiceManager用于对系统的服务进行创建、启动和生命周期管理。
3.启动各种系统服务。
分析一下SystemServer.java的代码(原谅我只分析java代码,cpp代码好多年不用了)
public static void main(String[] args) { new SystemServer().run(); }
进入run方法,发现里面做了很多事情
private void run() { try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices"); // If a device's clock is before 1970 (before 0), a lot of // APIs crash dealing with negative numbers, notably // java.io.File#setLastModified, so instead we fake it and // hope that time from cell towers or NTP fixes it shortly. if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } // If the system has "persist.sys.language" and friends set, replace them with // "persist.sys.locale". Note that the default locale at this point is calculated // using the "-Duser.locale" command line flag. That flag is usually populated by // AndroidRuntime using the same set of system properties, but only the system_server // and system apps are allowed to set them. // // NOTE: Most changes made here will need an equivalent change to // core/jni/AndroidRuntime.cpp if (!SystemProperties.get("persist.sys.language").isEmpty()) { final String languageTag = Locale.getDefault().toLanguageTag(); SystemProperties.set("persist.sys.locale", languageTag); SystemProperties.set("persist.sys.language", ""); SystemProperties.set("persist.sys.country", ""); SystemProperties.set("persist.sys.localevar", ""); } // Here we go! Slog.i(TAG, "Entered the Android system server!"); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis()); // In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system // property so that it is in sync. We can't do this in // libnativehelper's JniInvocation::Init code where we already // had to fallback to a different runtime because it is // running as root and we need to be the system user to set // the property. http://b/11463182 SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Enable the sampling profiler. if (SamplingProfilerIntegration.isEnabled()) { SamplingProfilerIntegration.start(); mProfilerSnapshotTimer = new Timer(); mProfilerSnapshotTimer.schedule(new TimerTask() { @Override public void run() { SamplingProfilerIntegration.writeSnapshot("system_server", null); } }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL); } // Mmmmmm... more memory! VMRuntime.getRuntime().clearGrowthLimit(); // The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage. VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // Some devices rely on runtime fingerprint generation, so make sure // we've defined it before booting further. Build.ensureFingerprintProperty(); // Within the system server, it is an error to access Environment paths without // explicitly specifying a user. Environment.setUserRequired(true); // Within the system server, any incoming Bundles should be defused // to avoid throwing BadParcelableException. BaseBundle.setShouldDefuse(true); // Ensure binder calls into the system always run at foreground priority. BinderInternal.disableBackgroundScheduling(true); // Increase the number of binder threads in system_server BinderInternal.setMaxThreads(sMaxBinderThreads); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false); Looper.prepareMainLooper(); // Initialize native services. System.loadLibrary("android_servers"); // Check whether we failed to shut down last time we tried. // This call may not return. performPendingShutdown(); // Initialize the system context. createSystemContext(); // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // Start services. try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices"); startBootstrapServices(); startCoreServices(); startOtherServices(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } // For debug builds, log event loop stalls to dropbox for analysis. if (StrictMode.conditionallyEnableDebugLogging()) { Slog.i(TAG, "Enabled StrictMode for system server main thread."); } // Loop forever. Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }
代码还算清晰,首先初始化一些时间、local、binder的最大进程数,启动Binder线程池啥的。
下来就是加载android_servers库,
紧接着就是创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
接下来就是启动系统的各种服务
上图可见,服务分为3类,
1、BootstrapServices为引导服务,启动的service包括:
Installer 系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务
ActivityManagerService 负责四大组件的启动、切换、调度。
PowerManagerService 计算系统中和Power相关的计算,然后决策系统应该如何反应
LightsService 管理和显示背光LED
DisplayManagerService 用来管理所有显示设备
UserManagerService 多用户模式管理
SensorService 为系统提供各种感应器服务
PackageManagerService 用来对apk进行安装、解析、删除、卸载等等操作
2、 CoreServices为核心服务,包括:
BatteryService 管理电池相关的服务
UsageStatsService 收集用户使用每一个APP的频率、使用时常
WebViewUpdateService WebView更新服务
3、OtherServices其他服务,包括很多服务,比如:
CameraService 摄像头相关服务
AlarmManagerService 全局定时器管理服务
InputManagerService 管理输入事件
WindowManagerService 窗口管理服务
VrManagerService VR模式管理服务
BluetoothService 蓝牙管理服务
NotificationManagerService 通知管理服务
DeviceStorageMonitorService 存储相关管理服务
LocationManagerService 定位管理服务
AudioService 音频相关管理服务
4、ActivityManagerService
这里主要讲一下,为啥Launcher启动出来会成为桌面,先来看一下ActivityManagerService(SystemService启动的一个引导服务)内的startHomeActivityLocked方法。boolean startHomeActivityLocked(int userId) { if(this.mHeadless) { this.ensureBootCompleted(); return false; } else if(this.mFactoryTest == 1 && this.mTopAction == null) { return false; } else { Intent intent = new Intent(this.mTopAction, this.mTopData != null?Uri.parse(this.mTopData):null); intent.setComponent(this.mTopComponent); if(this.mFactoryTest != 1) { intent.addCategory("android.intent.category.HOME"); } ActivityInfo aInfo = intent.resolveActivityInfo(this.mContext.getPackageManager(), 1024); if(aInfo != null) { intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name)); aInfo = new ActivityInfo(aInfo); aInfo.applicationInfo = this.getAppInfoForUser(aInfo.applicationInfo, userId); ProcessRecord app = this.getProcessRecordLocked(aInfo.processName, aInfo.applicationInfo.uid); if(app == null || app.instrumentationClass == null) { intent.setFlags(intent.getFlags() | 268435456); this.mMainStack.startActivityLocked((IApplicationThread)null, intent, (String)null, aInfo, (IBinder)null, (String)null, 0, 0, 0, 0, (Bundle)null, false, (ActivityRecord[])null); } } return true; } }
创建了一个Intent,并将mTopAction和mTopData传入。mTopAction的值为Intent.ACTION_MAIN,并且如果系统运行模式不是1(这个1是什么意思?)则将intent的Category设置为
android.intent.category.HOME。
而Launcher的AndroidManifest.xml文件里面给Launcher定义的category就是android.intent.category.HOME,
<activity android:name="com.android.launcher3.Launcher" android:launchMode="singleTask" android:clearTaskOnLaunch="true" android:stateNotNeeded="true" android:theme="@style/LauncherTheme" android:windowSoftInputMode="adjustPan" android:screenOrientation="nosensor" android:configChanges="keyboard|keyboardHidden|navigation" android:resumeWhilePausing="true" android:taskAffinity="" android:enabled="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.HOME" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.MONKEY"/> </intent-filter> </activity>
之后,就将含有这个属性的Launcher启动了
if(app == null || app.instrumentationClass == null) { intent.setFlags(intent.getFlags() | 268435456); this.mMainStack.startActivityLocked((IApplicationThread)null, intent, (String)null, aInfo, (IBinder)null, (String)null, 0, 0, 0, 0, (Bundle)null, false, (ActivityRecord[])null); }
至此,Launcher这个app作为一个home桌面就启动出来了。启动之后的界面划分和模块分析下一篇讲解。
相关文章推荐
- Kernel启动流程源码解析 2 head.S
- Android Zygote启动流程源码解析
- Android Activity启动流程源码解析
- Tomcat源码解析(五):Connector连接器的初始化和启动流程
- Android源码基础解析之Launcher启动流程
- Android源码解析四大组件系列(四)---Activity启动详细流程
- android源码解析之(十一)-->应用进程启动流程
- Kernel启动流程源码解析 5 start_kernel 下
- MTK Kernel启动流程源码解析 3 init_task
- MTK Kernel启动流程源码解析 5 start_kernel 下
- Flink源码解析之 --- 启动流程
- Android SystemServer启动流程源码解析
- Hadoop源码解析之ApplicationMaster启动流程
- Kernel启动流程源码解析 12 总结
- Android源码解析之(九)-->SystemServer进程启动流程
- Flume-ng源码解析之启动流程
- Kernel启动流程源码解析 6 setup_arch
- Kernel启动流程源码解析 1 head.S
- android源码解析之(九)-->SystemServer进程启动流程
- Android ContentProvider启动流程源码解析(8.0)