SystemServer到Launcher
通过前面对android 启动流程到SystemServer的分析,紧接着我们来到了本篇博客,介绍从 systemserver 到 launcher 的启动过程。
整体过程
从 SystemServer 到 Launcher 的过程其实就是从系统进程到应用进程的过程,他们之间通过binder通信来传递信息,并相互作用一起决定桌面应用(launcher)的启动。
整体流程图
上图详细介绍了从 systemserver.run 方法通过层层调用,最终将桌面应用程序launcher运行起来的过程。
重要基础知识点
Binder
可参考连接:http://www.jianshu.com/p/af2993526daf
简单点理解如下:
- Linux中存在进程隔离,用户空间中的进程不能相互访问,用户空间可以通过系统调用这个统一接口访问内核控件,系统调用时由内核控件运行。
- binder是一个IPC通信机制,Linux通过动态可加载内核模块机制,将binder驱动加载进了内核,内核具有访问所有进程资源的权限,android端的进程就可以通过binder驱动来跨进程访问。
- binder具有性能高而且较安全的优点,所有没有使用socket和管道子类的IPC通信机制。
- 两个运行在用户空间的进程要完成通信,必须借助内核的帮助,这个运行在内核里面的程序叫做Binder驱动,它的功能类似于基站;通信录呢,就是一个叫做ServiceManager的东西(简称SM)。
- sever向SM注册信息:数据流会通过binder驱动,所以binder驱动会对数据做点处理,此时,SM中存储的是server的代理对象。
- client向SM查询信息:同上,binder会给client返回一个objectProxy代理对象。所以client只是持有了server端的代理对象,代理对象和binder同时工作,完成了IPC通信。
- 在驱动中,Binder本地对象的代表是一个叫做binder_node的数据结构,Binder代理对象是用binder_ref代表的。
- 一个需要跨进程传递的对象一定继承自IBinder,如果是Binder本地对象,那么一定继承Binder实现IInterface(Stub对象),如果是代理对象,那么就实现了IInterface并持有了IBinder引用(Proxy对象)。
- 相当于server和client端都有XXX.aidl文件和编译器生成的XXX.java文件,其中真正其作用的是XXX.java文件,这个文件里面有一个Stub对象,代表的是binder本地对象,还有一个Proxy对象,代表的是binder代理对象,当通过asInterface方法时,会先在本进程搜索你要访问的对象是不是binder本地对象,如果是,则强制类型转换并返回,代表没有跨进程访问直接调用本进程方法,如果不是,则返回一个Proxy代理对象,然后使用Proxy通过binder驱动,调用远端server的Stub对象的相关方法,这里就进行了IPC访问。
- 一般Stub对象都会有一个继承它的类,并实现server中具体的方法。
AIDL
aidl 是基于binder通信机制来完成跨进程访问。参考: http://blog.csdn.net/luoyanglizi/article/details/51980630
简单理解如下:
在服务端进程:
- 创建一个XXX.aidl为后缀的文件,并定义具体方法的接口,然后IDE就会自动生成一个同名的XXX.java文件。
- 创建一个service在onBind的时候返回一个IBinder的对象,这个对象是刚才创建的接口对象的代理,private final XXX.Stub mBinder = new XXX.Stub()并实现里面的接口方法
在客户端进程:
- 先将服务端的XXX.aidl文件,copy到与服务器相同包路径下面 ,clear一下或者rebuild一下会自动生成XXX.java的文件。
- 通过bindService和ServiceConnection 连接到服务端进程。
- ServiceConnection.onServiceConnected 中通过XXX.Stub.asInterface(service) 得到 XXX.java对象。
- 通过 XXX 对象调用服务端的具体代码实现
反射
还不太了解,后续补上。
流程中的重要内容
systemserver的run方法里面
startBootstrapServices
开启一些引导服务,包括如下内容:
- Installer.class 获取权限并创建一些路径如:/data/user
- ActivityManagerService.Lifecycle.class设置SystemServiceManager、Installer、PowerManagement等
- PowerManagerService.class 负责协调设备电源管理,其他服务依赖于它
- LightsService.class 负责LED和背光显示
- DisplayManagerService.class 控制界面的显示
- RegionalizationService 区域服务
- UserManagerService.LifeCycle.class
- startSensorService 开始sensor服务
startCoreServices
开启一些之前没有打开的核心服务,包括如下:
- BatteryService.class 电池电量服务
- UsageStatsService.class 收集应用程序数据
- WebViewUpdateService.class webview更新服务
startOtherServices
启动一些其它的服务并调用一些核心的放,这里面涉及到的东西就比较多了,下面列举部分,读者可以自行查看源码。
TelecomLoaderService.class、TelephonyRegistry、CameraService.class、AlarmManagerService.class、 watchdog.init、WindowManagerService、InputManagerService、BluetoothService.class、AccessibilityManagerService、StatusBarManagerService、NetworkStatsService、WifiService 等等还有很多。。。。。。
ActivityManagerService
得到要启动界面launcher.java的action 和 category
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); //android.intent.action.MAIN 获取需要启动的activity
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
intent.addCategory(Intent.CATEGORY_HOME); //android.intent.category.HOME
}
return intent;
}
ActivityStack
通过binder实现systemserver和应用进程的通信
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
ActivityRecord resuming, boolean dontWait) {
.....省略部分代码
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);//通过binder通信调用ActivityThread.schedulePauseActivity 执行当前界面activity 的onPause 方法。
}
.....省略部分代码
}
ActivityThread
通过binder实现应用进程和systemserver的通信
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
.......省略部分代码
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);//通过binder通信调用 ActivityManagerService.activityPaused 通知activity pause完成
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
ActivityStackSupervisor
直接启动activity或者创建进程
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
.....省略部分代码
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);//如果要启动的activity所属进程已启动,那么直接启动activity
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);//如果activity所属进程没有启动,那么先创建该进程
}
ActivityThread
创建当前进程的主线程
public static void main(String[] args) {
.....省略部分代码
Looper.prepareMainLooper();//创建消息队列
ActivityThread thread = new ActivityThread(); //创建主线程
thread.attach(false);
.....省略部分代码
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();//开启消息循环
throw new RuntimeException("Main thread loop unexpectedly exited");
}
会执行到activity的onCreate、onResume等方法
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
......省略部分代码
Activity a = performLaunchActivity(r, customIntent);//最终会执行activity的onCreate方法
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
reportSizeConfigurations(r);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason); //最终会执行activity的onResume方法
......省略部分代码
}
参考:http://blog.csdn.net/qq_23547831/article/details/51224992
上一篇: linux nohup及tail-f用法
下一篇: linux下C语言实现写日志功能