新建aidl回调接口,用工具生成代码,并实现java/cpp服务端和测试代码。
基本流程和java端代码生成,cpp端代码生成 这两章差不多,都分为接口代码生成, 服务端代码,测试代码三部分。
一, 增加aidl回调接口
ICallback.aidl
1 2 3 4 5 6
   | package demo;
  interface ICallback {     void onCallback(String str); }
 
  | 
 
在ITest.aidl中增加注册回调接口
1 2 3 4 5 6 7 8 9 10
   | package demo;
  import demo.ICallback; interface ITest {     void ping();     int sum(int x, int y);     void registerCallback(ICallback cb);     void unregisterCallback(ICallback cb); }
 
  | 
 
二, JAVA端使用
2.1 java端回调代码生成
执行下面两条命令即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | $ out/host/linux-x86/bin/aidl -Iframeworks/native/cmds/binderdemo/aidl -oframeworks/native/cmds/binderdemo/java/src/ frameworks/native/cmds/binderdemo/ICallback.aidl $ out/host/linux-x86/bin/aidl -Iframeworks/native/cmds/binderdemo/aidl -oframeworks/native/cmds/binderdemo/java/src/ frameworks/native/cmds/binderdemo/aidl/demo/ITest.aidl $ tree  ├── aidl │   └── demo │       ├── ICallback.aidl │       └── ITest.aidl java/ ├── Android.mk ├── java_binder_test └── src     └── demo         ├── ICallback.java         ├── ITest.java         ├── Main.java         └── TestServer.java
 
 
  | 
 
这里解释下aidl工具的用法:
-I 指定aidl引用的目录,因为当时有引用demo.ICallback包
-o 指定生成目录
其它一些没有用到,没去研究就不作解释了。
2.2 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
   | private final RemoteCallbackList<ICallback> mCallbacks = new RemoteCallbackList<ICallback>();
  protected void doCallback(String info) {     if (mCallbacks == null || mCallbacks.getRegisteredCallbackCount() <= 0) {         Log.d(TAG, "doCallback error");         return;     }     synchronized (mCallbacks) {         mCallbacks.beginBroadcast();         int N = mCallbacks.getRegisteredCallbackCount();         Log.d(TAG, "doCallback Count = " + N);         for (int i = 0; i < N; i++) {             try {                 if (mCallbacks.getBroadcastItem(i) == null) {                     continue;                 }                 mCallbacks.getBroadcastItem(i).onCallback(info);             } catch (DeadObjectException e) {                 if (mCallbacks.getBroadcastItem(i) != null)                     mCallbacks.unregister(mCallbacks.getBroadcastItem(i));             } catch (RemoteException e) {                 e.printStackTrace();             }         }         mCallbacks.finishBroadcast();     } }
 
  | 
 
然后重写注册和反注册接口
1 2 3 4 5 6 7 8 9 10
   | @Override public void registerCallback(ICallback cb) throws RemoteException {     Log.d(TAG, "register " + cb);     if (cb != null) mCallbacks.register(cb); }
  @Override public void unregisterCallback(ICallback cb) throws RemoteException {     if (cb != null) mCallbacks.unregister(cb); }
 
  | 
 
最后就是回调方法的调用,我让执行ping函数后延时5秒回调
1 2 3 4 5 6 7 8 9 10
   | @Override public void ping() throws RemoteException {     Log.d(TAG, "ping receive ok, after 5s callback");     try {         Thread.sleep(5000);     } catch (InterruptedException e) {}
      Log.d(TAG, "ping doCallback");     doCallback("ping"); }
 
  | 
 
2.3 测试类Main.java
和注册死亡回调差不多, 注册之后执行ping函数,5s后会收到回调。
1 2 3 4 5 6 7 8 9 10 11 12 13
   | public static void main(String[] args) {     ...     testClient.registerCallback(new ICallback.Stub() {         @Override         public void onCallback(String str) throws RemoteException {             Log.d(TAG_C, "This is onCallback");         }     });
      Log.d(TAG_C, "ping, 5s callback");     testClient.ping();     ... }
 
  | 
 
三,CPP端使用
3.1 cpp端回调代码生成
执行下面两条指令即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
   | $ out/host/linux-x86/bin/aidl-cpp frameworks/native/cmds/binderdemo/aidl/demo/ICallback.aidl frameworks/native/cmds/binderdemo/cpp/include/ frameworks/native/cmds/binderdemo/cpp/ICallback.cpp $ out/host/linux-x86/bin/aidl-cpp -Iframeworks/native/cmds/binderdemo/aidl frameworks/native/cmds/binderdemo/aidl/demo/ITest.aidl frameworks/native/cmds/binderdemo/cpp/include/ frameworks/native/cmds/binderdemo/cpp/ITest.cpp $ tree ├── aidl │   └── demo │       ├── ICallback.aidl │       └── ITest.aidl ├── cpp │   ├── Android.mk │   ├── CMakeLists.txt │   ├── ICallback.cpp │   ├── ITest.cpp │   ├── include │   │   └── demo │   │       ├── BnCallback.h │   │       ├── BnTest.h │   │       ├── BpCallback.h │   │       ├── BpTest.h │   │       ├── ICallback.h │   │       └── ITest.h │   └── main.cpp
 
  | 
 
3.2 cpp服务端代码
远程回调的数组
1
   | std::vector<sp<demo::ICallback>> mCallbackList;
 
  | 
 
注册与反注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | binder::Status registerCallback(const sp<::demo::ICallback> &cb) override {     for (auto& it : mCallbackList) {         if (IInterface::asBinder(it) == IInterface::asBinder(cb)) {             INFO("%s: Tried to add callback %p which was already subscribed",                     __FUNCTION__, cb.get());             return binder::Status();         }     }
      mCallbackList.push_back(cb);     return binder::Status(); }
  binder::Status unregisterCallback(const sp<::demo::ICallback> &cb) override {     for (auto it = mCallbackList.begin(); it != mCallbackList.end(); it++) {         if (IInterface::asBinder(*it) == IInterface::asBinder(cb)) {             mCallbackList.erase(it);             INFO("server: unregisterCallback ok");             return binder::Status().ok();         }     }     return binder::Status(); }
 
  | 
 
回调方法的调用,还是执行ping函数后延时5秒回调
1 2 3
   | for (auto& i : mCallbackList) {     i->onCallback(String16("test")); }
 
  | 
 
3.3 测试类main.cpp
先注册回调,然后再解除注册
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
   | class CallbackTest : public demo::BnCallback { public:     binder::Status onCallback(const String16 &str) override {         INFO("client: onCallback, receive str: %s", String8(str).string());         return binder::Status();     } };
  int main(int argc, char **argv) {     sp<ProcessState> proc(ProcessState::self());     ProcessState::self()->startThreadPool();     sp<IServiceManager> sm = defaultServiceManager();     sp<IBinder> binder = sm->getService(String16(BINDER_NAME));     sp<demo::ITest> test = interface_cast<demo::ITest>(binder);     sp<CallbackTest> callback = new CallbackTest();     test->registerCallback(callback);     INFO("client: ping, 5s callback");     test->ping();
      test->unregisterCallback(callback);     INFO("client: ping again, 5s callback");     test->ping();     IPCThreadState::self()->joinThreadPool();     return 0; }
 
  | 
 
四, 源码
本章节源码在 https://github.com/hqw700/binderdemo/releases/tag/v0.4 下
操作系统:Windows 10 专业版 19042.685
编译机:WSL2 Ubuntu-18.04
手机:Google Pixel 1
源码版本:AOSP android-7.1.1_r35