Android - AMS源码分析
Android核心分析之AMS
App和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程
App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。
打开一个APP
Launcher
Launcher负责桌面图标的显示和控制,本质上也是一个应用程序,和我们的App一样,也是继承自Activity
以双击打开一个APP为例:
不管在哪里点击图标,都会调用
mLauncher.startActivitySafely(v, appInfo.intent, appInfo);
这个方法,最后调用startActivityForResult()
而startActivityForResult()调用的是mInstrumentation.execStartActivity()。
Instrumentation
AMS和ActivityThread之间的Binder通信
mInstrumentation.execStartActivity()接下来调用了这个方法
ActivityManagerNative.getDefault()
.startActivity
这里的ActivityManagerNative.getDefault返回的就是ActivityManagerService的远程接口,即ActivityManagerProxy。
再看ActivityManagerProxy.startActivity(),在这里面做的事情就是IPC通信,利用Binder对象,调用transact(),把所有需要的参数封装成Parcel对象,向AMS发送数据进行通信。
ActivityManagerNative源码:
public abstract class ActivityManagerNative extends Binder implements IActivityManager { //从类声明上,我们可以看到ActivityManagerNative是Binder的一个子类,而且实现了IActivityManager接口 static public IActivityManager getDefault() { return gDefault.get(); } //通过单例模式获取一个IActivityManager对象,这个对象通过asInterface(b)获得 private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } }; } //最终返回的还是一个ActivityManagerProxy对象 static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //这里面的Binder类型的obj参数会作为ActivityManagerProxy的成员变量保存为mRemote成员变量,负责进行IPC通信 return new ActivityManagerProxy(obj); } }
很清楚看到ActivityManagerNative继承Binder,是Binder本地对象。IActivityManager是远程接口,代表AMS能提供的功能。
ActivityManagerProxy是AMS的远程代理对象,Activity可以通过代理对象调用AMS提供的接口中方法。
所以App与AMS通过Binder进行IPC通信
AMS向ActivityThread通信
以上解释了activity向AMS通信的方法,
如果AMS想要通知ActivityThread做一些事情,应该咋办呢?
还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread和ApplicationThreadProxy。
private class ApplicationThread extends ApplicationThreadNative {} public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{} class ApplicationThreadProxy implements IApplicationThread {}
AMS接收到客户端的请求之后,会如何开启一个Activity?
可以看上面那个图,大致就是AMS得到activity栈的引用,然后根据启动模式添加到栈中,最后回调applicationThread执行原activity的pause
广播
为什么需要广播
广播是操作系统framework层对观察者模式(observer)最常用的实现方式
一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其它的对象做出相应的改变。做到这一点的设计方案有很多,但是为了使系统能够易于复用,应该选择低耦合度的设计方案。减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作。观察者模式是满足这一要求的各种设计方案中最重要的一种。
广播有无序广播、有序广播和粘性广播,其中粘性广播需要有BROADCAST_STICKY权限
Service
Service是什么
Service是Android系统的组件之一,和Activity,Broadcast,Conent Provider并称Android四大组件,Service是不可见的,是没有界面的,是在后台运行的,Service一般处理比较耗时以及长时间运行的操作
1. startService主要用于启动一个服务执行后台任务,不进行通信,停止服务使用stopService
2. bindService该方法启动的服务可以获得该service的状态,停止服务使用unbindService