-
监听服务端死亡
注意 onServiceDisconnected 只有在死亡意外死亡后才会回调,unbindService 不会回调
mServiceConn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, final IBinder service) { Log.d(TAG, "onServiceConnected"); try { // 设置服务死亡代理,服务死亡后可自动绑定服务 service.linkToDeath(new IBinder.DeathRecipient() { @Override public void binderDied() { Log.d(TAG, "binderDied"); service.unlinkToDeath(this, 0); bindService(); } }, 0); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { Log.d(TAG, "onServiceDisconnected"); playerService = null; } }
-
监听客户端死亡
private RemoteCallbackList<IMetadataUpdateCallback> callbacks = new RemoteCallbackList<IMetadataUpdateCallback>() { @Override public void onCallbackDied(IMetadataUpdateCallback callback) { super.onCallbackDied(callback); Log.d(TAG, "onCallbackDied:" + callback); } };
-
服务端收到的对象并不相同,BinderProxy是相同的
每个进程对应着一个VM,对象无法在进程间传递,binder机制数据传递是通过序列化进行的,
// 客户端 2022-07-16 15:38:39.900 9756-9756/com.example.aidl D/MainActivity: registerMetadataUpdateCallback: com.example.aidl.MainActivity$1@94bcaae asBinder:com.example.aidl.MainActivity$1@94bcaae // 服务端 2022-07-16 15:38:39.900 9789-9808/? D/PlayerService: registerMetadataUpdateCallback:com.example.aidl.IMetadataUpdateCallback$Stub$Proxy@4a38442 asBinder: android.os.BinderProxy@8f79c53 2022-07-16 15:39:00.620 9789-9808/com.example.aidl:Remote D/PlayerService: unregisterMetadataUpdateCallback:com.example.aidl.IMetadataUpdateCallback$Stub$Proxy@e410990 asBinder: android.os.BinderProxy@8f79c53
-
RemoteCallbackList作用
1.以IBinder-Callback的键值对形式,存储Callback,
2.添加死亡代理监听,自动清除Callback
3.将map中value复制到数据中,来保证多线程安全
4.源码mCallbacks用来存储Callback,mActiveBroadcast在调用时保存mCallbacks.values,来保证多线程安全
ArrayMap < IBinder, Callback > mCallbacks = new ArrayMap < IBinder, Callback > (); private Object[] mActiveBroadcast; public int beginBroadcast() { synchronized(mCallbacks) { if(mBroadcastCount > 0) { throw new IllegalStateException("beginBroadcast() called while already in a broadcast"); } final int N = mBroadcastCount = mCallbacks.size(); if(N <= 0) { return 0; } Object[] active = mActiveBroadcast; if(active == null || active.length < N) { mActiveBroadcast = active = new Object[N]; } for(int i = 0; i < N; i++) { active[i] = mCallbacks.valueAt(i); } return N; } } public E getBroadcastItem(int index) { return((Callback) mActiveBroadcast[index]).mCallback; } public void finishBroadcast() { synchronized(mCallbacks) { if(mBroadcastCount < 0) { throw new IllegalStateException("finishBroadcast() called outside of a broadcast"); } Object[] active = mActiveBroadcast; if(active != null) { final int N = mBroadcastCount; for(int i = 0; i < N; i++) { active[i] = null; } } mBroadcastCount = -1; } }
-
权限校验
可以在Service中onBind方法返回Binder对象时进行校验或者在自定义Binder类中onTransact进行校验
<permission android:name="com.example.aidl.BookService" android:protectionLevel="signature" /> <uses-permission android:name="com.example.aidl.BookService" />
@Override public IBinder onBind(Intent intent) { Log.d(TAG, "onBind"); if(checkCallingOrSelfPermission(PERMISSION) == PackageManager.PERMISSION_DENIED) { Log.d(TAG, "Bind PlayerService need permission example.permission.TEST_AIDL, are you have?"); return null; } return mBinder; }
-
数据流向
Directional Tag Desc in 数据从 caller传到 callee,callee 调用结束后不会把数据写回 caller 中 out caller 数据不会传入 callee(因为就没有写数据), callee 调用结束后(不管数据有没有更新)会把数据写回 caller 中 inout 数据从 caller 传到 callee,callee 调用结束后(不管数据有没有更新)会把数据写回 caller 中 参考:https://www.jianshu.com/p/31898ea2dfa3
基本数据类型只能为in,可以不用加,oneway 只能是in
-
oneway
-
binder默认是同步调用的,会挂起客户端直至完成,oneawy是异步调用
-
oneway 修饰的方法返回值只能是void
-
AIDL总结
于 2022-07-16 18:56:56 首次发布