通过 Handler 、Messenger、Message 实现跨进程通信(IPC)
- 实际传递的是Message,可以复用信息池
- 支持信息回调
- 不需要编写aidl
-
Server 端 MyService 实现 代码:
public class MyService extends Service { private static final int RECEIVE_MESSAGE_CODE = 0x0001; private static final int SEND_MESSAGE_CODE = 0x0002; //保存当前连接的所有 客户端. ArrayList<Messenger> mClients = new ArrayList<>(); static final int MSG_REGISTER_CLIENT = 1; static final int MSG_UNREGISTER_CLIENT = 2; static final int MSG_SET_VALUE = 3; private Messenger clientMessenger = null; private Messenger serviceMessenger = new Messenger(new ServiceHandler()); private class ServiceHandler extends Handler { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); Log.d("MyService", "handleMessage:" + msg.what); switch (msg.what) { case MSG_REGISTER_CLIENT: Log.d("MyService", "client added :" + msg.replyTo.toString()); mClients.add(msg.replyTo); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; case MSG_SET_VALUE: int a = msg.arg1; int b = msg.arg2; int c = a+b; for (int i = mClients.size() - 1; i >= 0; i--) { try { Thread.sleep(5000);//模拟耗时 // 给 客户端发消息 mClients.get(i).send(Message.obtain(null, MSG_SET_VALUE, c, 0)); } catch (RemoteException | InterruptedException e) { mClients.remove(i);// 客户端连接异常, 删除客户端 } } break; default: super.handleMessage(msg); } } }// end ServiceHandler @Override public IBinder onBind(Intent intent) { Log.d("MyService", "onBind:"); return serviceMessenger.getBinder(); } @Override public void onDestroy() { Log.d("MyService", "onDestroy:"); super.onDestroy(); clientMessenger = null; } }
-
Client 端 MainActivity 实现 代码:
public class MainActivity extends AppCompatActivity { private Button mBtBind; private Button mBtUnBind; private TextView mTvMsg; static final int MSG_REGISTER_CLIENT = 1; static final int MSG_UNREGISTER_CLIENT = 2; static final int MSG_SET_VALUE = 3; private boolean isBound = false; private String SERVICE_ACTION = "tk.iovr.messagehandlerservice.MyService"; private Messenger serviceMessenger = null; private Messenger clientMessenger = new Messenger(new ClientHandler()); private class ClientHandler extends Handler { @Override public void handleMessage(@NonNull Message msg) { super.handleMessage(msg); switch (msg.what) { case MSG_SET_VALUE: Log.d("MainActivity","Received value from service: " + msg.arg1); mTvMsg.setText("Received from service: " + msg.arg1); break; default: super.handleMessage(msg); } } } private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("MainActivity","onServiceConnected:"); serviceMessenger = new Messenger(service); isBound = true; mTvMsg.setText("Attached."); try { Message message = Message.obtain(null,MSG_REGISTER_CLIENT); message.replyTo = clientMessenger; serviceMessenger.send(message); int a = new Random().nextInt(10); int b = new Random().nextInt(10); Log.d("MainActivity","send to remote a:"+a+", b:"+b); // 调用 Server 端代码 message = Message.obtain(null,MSG_SET_VALUE, a,b); serviceMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } // 发送 参数变量 // Message msg = Message.obtain(); // msg.what =SEND_MESSAGE_CODE; // // Bundle data = new Bundle(); // data.putString("msg","你好,MyService,我是客户端"); // msg.setData(data); // // msg.replyTo = clientMessenger; // try { // serviceMessenger.send(msg); // } catch (RemoteException e) { // e.printStackTrace(); // } } @Override public void onServiceDisconnected(ComponentName name) { serviceMessenger = null; isBound = false; mTvMsg.setText("Disconnected."); Log.d("MainActivity","remote service disconnected:"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBtBind = findViewById(R.id.bound); mBtUnBind = findViewById(R.id.unbound); mTvMsg = findViewById(R.id.msgshow); mTvMsg.setText("Not attached."); mBtBind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (!isBound){ doBindService(); } } }); mBtUnBind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isBound){ doUnBindService(); } } }); } private void doBindService() { Log.d("mainActivity","doBindService"); //Android 11 查询其他应用 信息需要获取权限 详见 AndroidManifest.xml Intent intent = new Intent(SERVICE_ACTION); intent.setComponent(new ComponentName("tk.iovr.messagehandlerservice", "tk.iovr.messagehandlerservice.MyService")); mTvMsg.setText("Binding."); bindService(intent,connection,BIND_AUTO_CREATE);//绑定服务 isBound = true; } private void doUnBindService() { Log.d("mainActivity","doUnBindService"); if (isBound){ if (serviceMessenger !=null){ try { //发送解绑消息 Message message = Message.obtain(null,MSG_UNREGISTER_CLIENT); message.replyTo = clientMessenger; serviceMessenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } unbindService(connection); //解绑服务 isBound = false; mTvMsg.setText("Unbinding"); } } }
客户端 在 setComponent 来 BindService 时,Android 11 上面 查询其他 应用信息 需要进行权限申请:
-
第一种方式:只指定需要查询 的应用包名
<queries> <package android:name="tk.iovr.messagehandlerservice"/> </queries>
第二种方式:声明 查询所有应用信息的权限
-
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
- messenger 适合一个个消息传递,不适合高并发