上一小节我们添加了一个 java service,也写了一个 client 来做测试。但只是单向的从 client 调用 service,实际项目中我们经常是需要双向调用的。某些事件发生的时候,service 端需要通知 client 来处理。这节我们就来学习一下如何从 service 端回调 client。为了简单起见,我们直接在上一小节的代码基础上进行修改。
1. 使用 aidl 定义callback接口
在 frameworks/base/core/java/android/pure 目录下创建 ICallback.aidl
1 2 3 4
| package android.pure; interface ICallback { void onMessage(in String message); }
|
在 frameworks/base/Android.bp framework-defaults 模块中添加我们刚刚加的 aidl 文件
1
| "core/java/android/pure/ICallback.aidl",
|
然后进入 framework/base 目录执行 mm -j 命令编译 framework.jar 模块。
编译成功后,会在 out/soong/.intermediates/frameworks/base/framework/android_common/gen/aidl/frameworks/base/core/java/android/pure 目录生成 ICallback.java 这个文件。
2. 添加注册回调接口
修改 IHelloService.aidl 如下
1 2 3 4 5 6 7
| package android.pure; import android.pure.ICallback; interface IHelloService { void hello(in String name); void registerCallback(in int pid, in ICallback callback); void unregisterCallback(in int pid); }
|
HelloService.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
| package com.android.server;
import android.os.RemoteException; import android.pure.IHelloService; import android.pure.ICallback; import android.util.Log;
import java.util.HashMap; import java.util.Map;
public class HelloService extends IHelloService.Stub { private final String TAG = "HelloService"; private Map<Integer, ICallback> mClients;
public HelloService() { Log.d(TAG, "create hello service"); mClients = new HashMap<>(); }
@Override public void hello(String name) { Log.d(TAG, "hello " + name); try { for (ICallback callback : mClients.values()) { callback.onMessage("message from service"); } } catch (RemoteException e) { e.printStackTrace(); } }
@Override public void registerCallback(int pid, ICallback callback) { mClients.put(pid, callback); Log.d(TAG, "registerCallback client's size = " + mClients.size()); }
@Override public void unregisterCallback(int pid) { mClients.remove(pid); Log.d(TAG, "unregisterCallback client's size = " + mClients.size()); } }
|
我们把 client 传递过来的 callback 保存到 mClients 集合中,当 client 调用 hello 接口时, 遍历 mclients 把消息传递给 client。
3. client 注册回调接口
修改 PureSettings apk 中的 MainActivity
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 59 60 61 62 63 64 65 66 67 68 69 70
| package com.pure.settings;
import android.app.Activity; import android.os.Bundle; import android.os.RemoteException; import android.os.ServiceManager; import android.pure.ICallback; import android.pure.IHelloService; import android.util.Log; import android.view.View; import android.widget.Button;
public class MainActivity extends Activity {
private static final String TAG = "PureSettings"; private IHelloService service = null;
private Button button;
private ICallback callback = new ICallback.Stub() {
@Override public void onMessage(String message) throws RemoteException { Log.d(TAG, "onMessage:" + message); } };
private void test() { Log.d(TAG, "test"); try { service.hello("qiushao"); } catch (RemoteException e) { e.printStackTrace(); } }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); service = IHelloService.Stub.asInterface(ServiceManager.getService("HelloService")); button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { test(); } }); }
@Override protected void onResume() { super.onResume(); try { service.registerCallback(android.os.Process.myPid(), callback); } catch (RemoteException e) { e.printStackTrace(); } }
@Override protected void onStop() { super.onStop(); try { service.unregisterCallback(android.os.Process.myPid()); } catch (RemoteException e) { e.printStackTrace(); } } }
|
4. 编译验证
整编系统,运行虚拟机,打开 PureSettings 测试,查看 logcat
1 2 3 4 5 6 7
| pure:/ # logcat -s HelloService:D PureSettings:D 02-02 22:57:37.913 1769 1769 D HelloService: create hello service 02-02 22:57:53.498 1769 3058 D HelloService: registerCallback client's size = 1 02-02 22:57:56.587 3580 3580 D PureSettings: test 02-02 22:57:56.587 1769 3058 D HelloService: hello qiushao 02-02 22:57:56.588 3580 3580 D PureSettings: onMessage:message from service 02-02 22:58:01.160 1769 3503 D HelloService: unregisterCallback client's size = 0
|
从 log 上看,client 收到了 service 传递过来的消息。