前言
做为一个Android开发,Context.getSystemService是非常常用的API,但你有了解过这个API是如何实现的吗?今天,让我们一起从源码角度分析一下这个API的具体实现吧。本文源码基于Android 2.3.7_r1。
分析过程
ContextImpl.java
1 2 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
| @Override public 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
1 2 3 4 5 6 7
| public List<RunningAppProcessInfo> getRunningAppProcesses() { try { return ActivityManagerNative.getDefault().getRunningAppProcesses(); } catch (RemoteException e) { return null; } }
|
我们发现ActivityManager做了一层转发,把请求转移到ActivityManagerNative去了,我们再来看下ActivityManagerNative具体做了哪些逻辑
ActivityManagerNative.java
1 2 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
1 2 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就会快很多。
参考