Android中的IPC方式——Binder(一)
Android中的IPC方式——Binder(二)
基于Android5.1.1分析,因为API26以后底层相关代码变动。
在client 中 通过bindservice来启动,来看下bindservice源码。 其具体是在
/frameworks/base/core/java/android/app/ContextImpl.java
@Override public boolean bindService(Intent service, ServiceConnection conn,int flags) { warnIfCallingFromSystemProcess(); return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser()); } private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, UserHandle user) { ... int res = ActivityManagerNative.getDefault().bindService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, user.getIdentifier()); ... } 复制代码
public abstract class ActivityManagerNative extends Binder implements IActivityManager{ /** * //最终返回的还是一个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的一个子类,而且实现了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; } }; } 复制代码
public interface IActivityManager extends IInterface { ... public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType,IServiceConnection connection, int flags, int userId) throws RemoteException; public boolean unbindService(IServiceConnection connection) throws RemoteException; ... } 复制代码
ActivityManagerNative.getDefault()获得IActivityManager,IActivitymanager继承于IInterface,这个结构是不是跟我们之前看的IStudentManager很像,那么 IActivityManager.bindservice()
,应该由它的静态内部类 Proxy
来实现。但是IActivityManager内部类并没有,其实是通过其他类来实现同样功能只是名称换了。这个类就是ActivityManagerNative。
public abstract class ActivityManagerNative extends Binder implements IActivityManager{ ... @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException { switch (code) { case BIND_SERVICE_TRANSACTION: data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); IBinder token = data.readStrongBinder(); Intent service = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); b = data.readStrongBinder(); int fl = data.readInt(); int userId = data.readInt(); IServiceConnection conn = IServiceConnection.Stub.asInterface(b); int res = bindService(app, token, service, resolvedType, conn, fl, userId); reply.writeNoException(); reply.writeInt(res); return true; } } ... class ActivityManagerProxy implements IActivityManager{ ... public ActivityManagerProxy(IBinder remote){ mRemote = remote; } public IBinder asBinder() { return mRemote; } ... public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection,int flags, int userId) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeStrongBinder(token); service.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(connection.asBinder()); data.writeInt(flags); data.writeInt(userId); mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0); reply.readException(); int res = reply.readInt(); data.recycle(); reply.recycle(); return res; } } 复制代码
可以看到ActivityManagerNative继承Binder实现IActivityManager,ActivityManagerNative就相当于Stub。
ActivityManagerProxy就是Proxy。
通过调用到的 mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
调用到Stub中的 onTranact()
,而Stub的具体实现类则是Activity'ManagerService,最后就是在ActivityManagerService中的 bindservice()
。
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { final ActiveServices mServices; public int bindService(IApplicationThread caller, IBinder token,Intent service, String resolvedType,IServiceConnection connection, int flags, int userId) { enforceNotIsolatedCaller("bindService"); // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } synchronized(this) { return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, userId); } } } 复制代码
bindservice主要分为四种情况
public final class ActiveServices { ... int bindServiceLocked(IApplicationThread caller, IBinder token,Intent service, String resolvedType,IServiceConnection connection, int flags, int userId) { ... if ((flags&Context.BIND_AUTO_CREATE) != 0) { s.lastActivity = SystemClock.uptimeMillis(); if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) { return 0; } } ... //进程启动service也创建的情况下并且绑定了, 回调onRebind() if (s.app != null && b.intent.received) { // Service is already running, so we can immediately // publish the connection. try { c.conn.connected(s.name, b.intent.binder); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + s.shortName + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")", e); } // If this is the first app connected back to this binding, // and the service had previously asked to be told when // rebound, then do so. if (b.intent.apps.size() == 1 && b.intent.doRebind) { requestServiceBindingLocked(s, b.intent, callerFg, true); } } else if (!b.intent.requested) { requestServiceBindingLocked(s, b.intent, callerFg, false); } ... } ... //server整个进程都没有启动,server进程启动了,但是里面的service没有创建 private final String bringUpServiceLocked(ServiceRecord r,int intentFlags, boolean execInFg, boolean whileRestarting) { if (!isolated) { app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); if (app != null && app.thread != null) {//进程启动了service没有创建 try { app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats); realStartServiceLocked(r, app, execInFg); return null; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } // If a dead object exception was thrown -- fall through to // restart the application. } } //进程未启动的情况 if (app == null) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", r.name, false, isolated, false)) == null) { String msg = "Unable to launch app " + r.appInfo.packageName + "/" + r.appInfo.uid + " for service " + r.intent.getIntent() + ": process is bad"; Slog.w(TAG, msg); bringDownServiceLocked(r); return msg; } if (isolated) { r.isolatedProc = app; } } } private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), ... } } 复制代码
对应的上述四种情况
server整个进程都没有启动 bindServiceLocked()
-> bringUpServiceLocked()
通过 mAm.startProcessLocked()
启动进程, bringDownServiceLocked(r);
来启动服务。
server进程启动了,但是里面的service没有创建 bindServiceLocked()
-> bringUpServiceLocked()
-> realStartServiceLocked(r, app, execInFg);
后续跟一下
server进程启动了,里面的service也创建了,但是没有绑定过,回调onBind()
bindServiceLocked()
-> requestServiceBindingLocked(s, b.intent, callerFg, false);
server进程启动了,里面的service创建了,也被绑定过,回调onRebind() bindServiceLocked()
-> requestServiceBindingLocked(s, b.intent, callerFg, true);
第一种情况没什么好说的,看一下第二种情况,从上面代码看到 realStartServiceLocked()
调用了 scheduleCreateService()
public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) { updateProcessState(processState, false); CreateServiceData s = new CreateServiceData(); s.token = token; s.info = info; s.compatInfo = compatInfo; sendMessage(H.CREATE_SERVICE, s); } public void handleMessage(Message msg) { ... case CREATE_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... } private void handleCreateService(CreateServiceData data) { ... try { java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } } ... } 复制代码
这里可以看到最后通过反射来创建service。
第三、四种情况,都是调用的从ActiveService中 requestServiceBindingLocked()
只是最后一个参数不一样。
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean execInFg, boolean rebind) { if (r.app == null || r.app.thread == null) { // If service is not currently running, can't yet bind. return false; } if ((!i.requested || rebind) && i.apps.size() > 0) { try { bumpServiceExecutingLocked(r, execInFg, "bind"); r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState); if (!rebind) { i.requested = true; } i.hasBound = true; i.doRebind = false; } catch (RemoteException e) { if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r); return false; } } return true; } 复制代码
发现跟调用到 ActivityThread.java
的 scheduleBindService()
public final void scheduleBindService(IBinder token, Intent intent, boolean rebind, int processState) { updateProcessState(processState, false); BindServiceData s = new BindServiceData(); s.token = token; s.intent = intent; s.rebind = rebind; if (DEBUG_SERVICE) Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); sendMessage(H.BIND_SERVICE, s); } public void handleMessage(Message msg) { ... case BIND_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); handleBindService((BindServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... } private void handleBindService(BindServiceData data) { Service s = mServices.get(data.token); if (DEBUG_SERVICE) Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); if (s != null) { try { data.intent.setExtrasClassLoader(s.getClassLoader()); data.intent.prepareToEnterProcess(); try { if (!data.rebind) { IBinder binder = s.onBind(data.intent); //重点 ActivityManagerNative.getDefault().publishService( data.token, data.intent, binder); } else { s.onRebind(data.intent); ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } ensureJitEnabled(); } catch (RemoteException ex) { } } catch (Exception e) { if (!mInstrumentation.onException(s, e)) { throw new RuntimeException( "Unable to bind to service " + s + " with " + data.intent + ": " + e.toString(), e); } } } } 复制代码
最后调用 handleBindService()
首先从mServices在这个map去取服务,服务不为空后,根据flag来判断调用onBind()还是 onReind(),s.onBind(data.intent)返回Binder。这个可以根据前面aidl使用的部分,service在 OnBind()
方法需要返回一个IBineder,而这个IBinder是 IStudentManager.Stub,由Service实现。
public void publishService(IBinder token, Intent intent, IBinder service) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } synchronized(this) { if (!(token instanceof ServiceRecord)) { throw new IllegalArgumentException("Invalid service token"); } mServices.publishServiceLocked((ServiceRecord)token, intent, service); } } 复制代码
public void publishService(IBinder token, Intent intent, IBinder service) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } synchronized(this) { if (!(token instanceof ServiceRecord)) { throw new IllegalArgumentException("Invalid service token"); } mServices.publishServiceLocked((ServiceRecord)token, intent, service); } } 复制代码
void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) { ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); ConnectionRecord c = clist.get(i); ... try { c.conn.connected(r.name, service); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + r.name + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")", e); } .... } 复制代码
到这里可以看到我们在service实现的onBind方法返回的 IBinder对象通过 publishService()
-> publishServiceLocked()
传递。
final class ConnectionRecord { final AppBindRecord binding; // The application/service binding. final ActivityRecord activity; // If non-null, the owning activity. final IServiceConnection conn; ... } 复制代码
c.conn.connected(r.name, service);
传递的service 就是我们刚刚的IBinder,c.conn最终指的是IServiceConnection,具体实现为
static final class ServiceDispatcher { ... private static class InnerConnection extends IServiceConnection.Stub { final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; InnerConnection(LoadedApk.ServiceDispatcher sd) { mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd); } public void connected(ComponentName name, IBinder service) throws RemoteException { LoadedApk.ServiceDispatcher sd = mDispatcher.get(); if (sd != null) { sd.connected(name, service); } } } ... public void connected(ComponentName name, IBinder service) { if (mActivityThread != null) { mActivityThread.post(new RunConnection(name, service, 0)); } else { doConnected(name, service); } } } private final class RunConnection implements Runnable { RunConnection(ComponentName name, IBinder service, int command) { mName = name; mService = service; mCommand = command; } public void run() { if (mCommand == 0) { doConnected(mName, mService); } else if (mCommand == 1) { doDeath(mName, mService); } } final ComponentName mName; final IBinder mService; final int mCommand; } public void doConnected(ComponentName name, IBinder service) { ... // If there was an old service, it is not disconnected. if (old != null) { mConnection.onServiceDisconnected(name); } // If there is a new service, it is now connected. if (service != null) { mConnection.onServiceConnected(name, service); } } 复制代码
mActivityThread.post(new RunConnection(name, service, 0));在RunConnection的run方法中调用了doConnected方法,doConnected()中调用了 onServiceDisconnected()
和 onServiceConnected()
这个就是由我们client端创建serviceConnetion时需要实现的方法。这样最终在客户端的 onServiceConnected()
获取了由service实现的IBinder。
整个的流程走完了,在我们刚刚分析中无论是AMS 还是 后面的IService 基本上都看到了类似 Binder的 方式。
AIDL接口 | Stub | Proxy | Stub实现类 |
---|---|---|---|
IStudentManager.aidl | IStudentManager.Stub | IStudentManager.Proxy | StudentManagerService |
IActivityManager | ActivityManagerNative | ActivityManagerProxy | ActivityManagerService |
在我们的实际项目中会使用到非常多的系统服务,这时候也是需要进行进程间通信,他们都存在不同的进程中,如果都通过aidl方式来调用就会很繁琐。所以Android给我提供了ServiceManager来统一管理。