本帖最后由 黄健 于 2015-12-28 14:29 编辑
跨进程通信:Messenger信使
在Android开发中,经常会涉及到Activity与Service互相交互的场景,Activity作为应用的前台交互界面,Service作为应用的后台服务,当用户触摸了交互界面时,Activity去请求Service做业务操作,Service根据Activity发来的请求做出相应的业务逻辑操作,如:访问网络、播放音乐、操作文件等,然后再把处理的结果返回给Activity,这时Activity拿到响应结果去更新界面,最终反馈给用户。实现Activity与Service交互的方法有多种,这里就介绍一下怎么使用Messenger进行Activity与Service互相交互。
使用Messenger进行Activity与Service互相交互 先来看一下Messenger类:Messenger创建时拥有一个消息处理器(Handler),Messenger可以发送消息,也可以处理消息,当使用Messenger发送消息后,它自己的消息处理器就接收到消息并进行处理。 那么,使用Messenger进行Activity与Service交互的实现机制就是:Activity和Service都创建一个Messenger对象,然后把自己的Messenger对象传递给对方,接着Activity和Service就可以拿对方传递过来的Messenger对象给对方发送消息,然后在Messenger的消息处理器里面处理对方使用自己的Messenger对象发过来的消息。 接下来,就可以用代码一步步去实现了。既然是Activity与Service交互,那就首先需要Activity与Service这两个组件。
第1步:创建Service类,命名MessageService继承Service。 public class MessengerServiceextends Service{ @Override public IBinder onBind(Intent intent) { return null; } }
第2步:Activity要想和Service交互,必须让Activity绑定Service,所以要实现Service的onBind方法,为了把自己的Messenger对象传递给Activity,在onBind方法里面返回自己的Messenger的IBinder对象。 // 创建Messenger对象,并给传递一个处理消息的Handler private final MessengermMessenger = new Messenger(new ServiceIncomingHandler()); @Override public IBinder onBind(Intentintent) { return mMessenger.getBinder();// 把Messenger的IBinder对象返回给Activity } // 用来处理Activity发过来的Message private class ServiceIncomingHandlerextends Handler { @Override public void handleMessage(Message msg) { } }
第3步:创建Activity,并绑定MessageService,绑定成功后,拿到MessageService返回来的IBinder对象生成Messenger对象,同时再创建一个自己的Messenger对象,并把自己的Messenger发送给MessageService。此时Activity已经可以给Service发送消息了。 public classMessengerActivity extends Activity { // 从MessageService返回来的Messenger private Messenger mService; // 自己的Messenger private final Messenger mMessenger = newMessenger(new ActivityIncomingHandler()); @Override protected void onCreate(BundlesavedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 绑定Service,为了拿到Service中的Messenger bindService(new Intent(this,MessengerService.class), mConnection,Context.BIND_AUTO_CREATE); } private ServiceConnection mConnection = newServiceConnection() { public voidonServiceConnected(ComponentName className, IBinder service) { // 用Service返回来的IBinder生成Messenger,相当于拿到Service的Messenger // 用来给Service发送消息 mService = new Messenger(service); Message msg =Message.obtain(null,MessageConstant.MSG_REGISTER_CLIENT); // 把自己的Messenger发送给Service,以便Service拿着给我发消息 msg.replyTo = mMessenger; mService.send(msg); } public voidonServiceDisconnected(ComponentName className) { mService = null; } }; private class ActivityIncomingHandlerextends Handler { @Override public void handleMessage(Message msg){ } } }
第4步:在第3步中,MessengerActivity已经把它的Messenger赋值给msg.replyTo并且发过来,接着就可以在MessageService的消息处理器中,把MessengerActivity发过来的Messenger取出来并保存。此时Service也可以给Activity发送消息了。 // Service可以被多个Activity绑定,用来记录所有Activity发过来的Messenger privateArrayList<Messenger> mClients = new ArrayList<Messenger>(); private classServiceIncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { caseMessageConstant.MSG_REGISTER_CLIENT: mClients.add(messenger);// 保存Activity发送过来的Messenger break; } } }
第5步:Activity与Service通过Messenger互相发送消息,根据Message的what值来判断消息类型。为了统一管理消息类型,把所有消息的what值放在常量类MessageConstant里。 public class MessageConstant{ public static final int MSG_REGISTER_CLIENT= 1; public static final intMSG_REQUEST_SERVICE_LOGIN = 3;// 请求登录 public static final intMSG_RESPONSE_CLIETN_LOGINOK = 4;// 登录成功 } ------------------------------------分割线----------------------------------------- MessengerActivity.java 代码片段: // 点击登录按钮时,给Service发送消息让它去访问服务器 public void login(View v){ sendMessageToService(Message.obtain(null,MessageConstant.MSG_REQUEST_SERVICE_LOGIN)); } private void sendMessageToService(Messagemsg) { try { mService.send(msg); } catch (RemoteException e) { } } private classActivityIncomingHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { caseMessageConstant.MSG_RESPONSE_CLIETN_LOGINOK: // 处理服务器返回来的登录成功消息 Toast.makeText(getApplicationContext(),"登录成功", 0).show(); break; } } } ------------------------------------分割线----------------------------------------- MessageService.java 代码片段: private classServiceIncomingHandler extends Handler { @Override public void handleMessage(Message msg){ switch (msg.what) { caseMessageConstant.MSG_REGISTER_CLIENT: mClients.add(messenger);// 保存Activity发送过来的Messenger caseMessageConstant.MSG_REQUEST_SERVICE_LOGIN: // 处理登录业务 login(msg); break; } } } private void login(Messagemsg) { // 开启线程,访问服务器 ... // 给Activity发送登录成功的消息,让Activity更新界面sendMessageToAllClient(Message.obtain(null,MessageConstant.MSG_RESPONSE_CLIETN_LOGINOK)); } // 给Activity发送消息的方法 private voidsendMessageToAllClient(Message message) { // 给所有的cliet发送响应消息 for (int i = 0; i < mClients.size();i++) { mClients.get(i).send(Message.obtain(message)); } } }
|