SystemServer到Launcher
来源:互联网 发布:怎么获取股票数据 编辑:程序博客网 时间:2024/06/11 17:28
通过前面对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
- SystemServer到Launcher
- android 启动流程到SystemServer
- SystemServer
- 从Android init.rc到SystemServer.java
- Ubuntu 添加应用程序到Launcher
- 【Launcher】获取最新Launcher源码,并且导入到Android Studio
- SystemServer 分析
- Android SystemServer
- SystemServer systemReady()
- SystemServer分析
- 了解systemServer
- Port ADW-Launcher到donut版本
- Ubuntu 16.04改变Launcher位置到底部
- android launcher 之踩到的坑
- Ubuntu16.04 launcher 调整到底部
- Launcher
- Launcher
- Launcher
- linux ubuntu环境下安装jdk(要求网络畅通有一定网速)
- Linux命令行
- shell 脚本编程学习(三) 条件控制,循环控制
- ExtJS Button调用Ext.window.Window后,只能点开一次,第二次就点不开
- Shop项目Servlet抽取
- SystemServer到Launcher
- 库vector函数的熟悉
- linux 性能测试监控shell脚本
- Docker安装以及registry搭建
- 解决linux普通用户使用Wireshark的权限不足问题
- RecyclerView指定布局管理器
- 为windows环境的elasticsearch更新license授权文件
- MySQL TRIGGER
- PRML之多项式曲线拟合