Android(安卓)Service、Messenger进程间通信
Android进程间通信有很多种,这里记录使用Service和Messenger来通信。在开始之前需要了解一下Android组件之Service。
Aandroid组件使用Service有两种方式,一种是启动方式,第二种是绑定方式。因为第一种启动方式,在启动Service之后,不会得到Service的任何返回,所以对Service的控制不是很好,没有更多的交互。而第二种绑定方式,在Android绑定Service之后,Service会给调用方组件返回一个IBinder对象。这样的方式就可以进行进程间通信。
下面看服务端代码:
//服务端public class MessengerService extends Service { private static final String TAG = "MessengerService"; private static final int MESSAGE_TYPE_ONE = 1; private static final int MESSAGE_TYPE_TEO = 2; private static final int MESSAGE_TYPE_THR = 3; private Messenger messenger; public MessengerService() { messenger = new Messenger(new MyHandler()); } @Override public void onCreate() { super.onCreate(); Log.d(TAG, "onCreate: "); } @Override public IBinder onBind(Intent intent) { if(intent!=null){ Log.d(TAG, "onBind: return ok"); return messenger.getBinder(); }else{ Log.d(TAG, "onBind: handler null"); return null; } } @Override public boolean onUnbind(Intent intent) { Log.d(TAG, "onUnbind: "); return super.onUnbind(intent); } @Override public void onDestroy() { Log.d(TAG, "onDestroy: "); super.onDestroy(); } static class MyHandler extends Handler{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Messenger messenger = msg.replyTo; Message message = null; Bundle bundle = new Bundle(); switch (msg.what){ case MESSAGE_TYPE_ONE:{ message = Message.obtain(null,1); bundle.putString("msg","hello one"); break; } case MESSAGE_TYPE_TEO:{ message = Message.obtain(null,2); bundle.putString("msg","hello teo"); break; } case MESSAGE_TYPE_THR:{ message = Message.obtain(null,3); bundle.putString("msg","hello three"); break; } } try { if (message!=null) { message.setData(bundle); messenger.send(message); }else { Log.d(TAG, "handleMessage: message null"); } } catch (RemoteException e) { e.printStackTrace(); } } }}
上述代码中,与平常的绑定Service方式略有不同,这里不用创建内部Binder子类,但是需要创建一个Messenger对象,onBinder方法返回的IBinder是Messenger中的IBinder。客户端接收到这个Binder之后,使用这个Binder创建一个Messenger对象,这样客户端与服务端的Messenger对象使用同一个IBinder,进程间通信就没有问题了。
客户端代码:
//客户端 private void initServiceConnection(){ Log.d(TAG, "initServiceConnection: "); serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mRemoteMessenger = new Messenger(service); } @Override public void onServiceDisconnected(ComponentName name) { mRemoteMessenger = null; } }; } private void initMessenger(){ Log.d(TAG, "initMessenger: "); messenger = new Messenger(new MyHandler()); } private void bindService(){ Log.d(TAG, "bindService: "); Intent intent = new Intent(); intent.setPackage("com.junxu.servicelearn"); intent.setAction("com.junxu.servicelearn.MyBinderService"); bindService(intent,serviceConnection, Service.BIND_AUTO_CREATE); } private void unBindService(){ Log.d(TAG, "unBindService: "); unbindService(serviceConnection); } private void sendMessage(){ Log.d(TAG, "sendMessage: "); try { Message message = Message.obtain(null,1); message.replyTo = messenger; mRemoteMessenger.send(message); } catch (RemoteException e) { Log.d(TAG, "sendMessage: "+e.getMessage()); e.printStackTrace(); }catch (Exception e){ e.printStackTrace(); } } static class MyHandler extends Handler{ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Log.d(TAG, "handleMessage: "+msg.getData().getString("msg")); } }
可以看到,客户端创建Messenger对象的时候,传入了IBinder对象,这个IBinder对象是服务器端返回来的。发送消息的时候使用的是这个Messenger对象。在客户端还创建了一个Messenger对象,这个对象创建的时候传入一个Handler对象,这个Messenger对象是传递到服务端的,供服务端回复消息的使用。从上面服务端代码可以看到,发送消息的Messenger对象是从客户端接收到的Message对象中获取的。而创建这个Messenger对象的时候传入的Handler就是用于处理服务端返回消息的。
另一个需要注意点:客户端绑定Service的时候。使用的是隐式绑定,这里的intent不单止需要设置action还需要设置包名,否则会报错:Service Intent must be explicit: Intent。这是Android5.0之后隐式绑定Service的一个更改
更多相关文章
- Android(安卓)ListFragment
- Android(安卓)Canvas绘图抗锯齿解决方法
- Android基础——通过activity和XML绑定实现按钮点击事件
- android中下载文件到SD卡的方法
- ktolin开发android的扩展包android-ktx
- Android(安卓)-- Vold机制简要分析
- Android(安卓)Asynchronous Http Client-Android异步网络请求客
- Android百度地图Poi检索开发总结
- Android(安卓)Messenger 进程间通信