前言
做为一个Android开发,Context.getSystemService是非常常用的API,但你有了解过这个API是如何实现的吗?今天,让我们一起从源码角度分析一下这个API的具体实现吧。本文源码基于Android 2.3.7_r1。
分析过程
ContextImpl.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 
 | @Overridepublic Object getSystemService(String name) {
 
 if (WINDOW_SERVICE.equals(name)) {
 return WindowManagerImpl.getDefault();
 } else if (ACTIVITY_SERVICE.equals(name)) {
 return getActivityManager();
 } else if (ALARM_SERVICE.equals(name)) {
 return getAlarmManager();
 } else if (ACCOUNT_SERVICE.equals(name)) {
 return getAccountManager();
 }
 
 return null;
 }
 
 
 private AccountManager getAccountManager() {
 synchronized (mSync) {
 if (mAccountManager == null) {
 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
 IAccountManager service = IAccountManager.Stub.asInterface(b);
 mAccountManager = new AccountManager(this, service);
 }
 return mAccountManager;
 }
 }
 
 private ActivityManager getActivityManager() {
 synchronized (mSync) {
 if (mActivityManager == null) {
 mActivityManager = new ActivityManager(getOuterContext(),
 mMainThread.getHandler());
 }
 }
 return mActivityManager;
 }
 
 private AlarmManager getAlarmManager() {
 synchronized (sSync) {
 if (sAlarmManager == null) {
 IBinder b = ServiceManager.getService(ALARM_SERVICE);
 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
 sAlarmManager = new AlarmManager(service);
 }
 }
 return sAlarmManager;
 }
 
 private ActivityManager getActivityManager() {
 synchronized (mSync) {
 if (mActivityManager == null) {
 mActivityManager = new ActivityManager(getOuterContext(),
 mMainThread.getHandler());
 }
 }
 return mActivityManager;
 }
 
 | 
ActivityManager.java
| 12
 3
 4
 5
 6
 7
 
 | public List<RunningAppProcessInfo> getRunningAppProcesses() {try {
 return ActivityManagerNative.getDefault().getRunningAppProcesses();
 } catch (RemoteException e) {
 return null;
 }
 }
 
 | 
我们发现ActivityManager做了一层转发,把请求转移到ActivityManagerNative去了,我们再来看下ActivityManagerNative具体做了哪些逻辑
ActivityManagerNative.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 
 | public abstract class ActivityManagerNative extends Binder implements IActivityManager{
 
 
 
 
 static public IActivityManager asInterface(IBinder obj)
 {
 if (obj == null) {
 return null;
 }
 IActivityManager in =
 (IActivityManager)obj.queryLocalInterface(descriptor);
 if (in != null) {
 return in;
 }
 
 return new ActivityManagerProxy(obj);
 }
 
 
 
 
 static public IActivityManager getDefault()
 {
 if (gDefault != null) {
 
 
 return gDefault;
 }
 IBinder b = ServiceManager.getService("activity");
 if (Config.LOGV) Log.v(
 "ActivityManager", "default service binder = " + b);
 gDefault = asInterface(b);
 if (Config.LOGV) Log.v(
 "ActivityManager", "default service = " + gDefault);
 return gDefault;
 }
 
 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
 throws RemoteException {
 Parcel data = Parcel.obtain();
 Parcel reply = Parcel.obtain();
 data.writeInterfaceToken(IActivityManager.descriptor);
 mRemote.transact(GET_RUNNING_APP_PROCESSES_TRANSACTION, data, reply, 0);
 reply.readException();
 ArrayList<ActivityManager.RunningAppProcessInfo> list
 = reply.createTypedArrayList(ActivityManager.RunningAppProcessInfo.CREATOR);
 data.recycle();
 reply.recycle();
 return list;
 }
 }
 
 | 
我们发现getDefault()方法先去ServiceManager查询到”activity”服务的句柄,然后通过asInterface方法生成一个本地代理类ActivityManagerProxy,最后该代理类再用ServiceManager查询出来的句柄去做真正的binder通信。所以当第一次去请求的时候,会有触发两次binder通信,一次是具体的业务逻辑请求,一次是ServiceManager去请求对应服务的binder,请求回来之后会保存在一个map中,所以第二次再调用getRunningAppProcesses(),只会有一次binder通信。
ServiceManager.java
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 
 | public final class ServiceManager {private static final String TAG = "ServiceManager";
 
 private static IServiceManager sServiceManager;
 private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
 
 private static IServiceManager getIServiceManager() {
 if (sServiceManager != null) {
 return sServiceManager;
 }
 
 
 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
 return sServiceManager;
 }
 
 public static IBinder getService(String name) {
 try {
 IBinder service = sCache.get(name);
 if (service != null) {
 return service;
 } else {
 return getIServiceManager().getService(name);
 }
 } catch (RemoteException e) {
 Log.e(TAG, "error in getService", e);
 }
 return null;
 }
 }
 
 
 | 
总结
Stub/Proxy/Service/ServiceManager组成了整个Framework通信框架。分析系统服务之前,找到对应的Stub/Proxy/Service,不管是ActivityManager,AccountManager, AlarmManager,亦或是WindowManager等等,都是一样的套路,通过这样的方式,举一反三,触类旁通,去分析理解其他的Manager就会快很多。
参考