使用Messenger
上面的方法只能在同一个进程里才能用,如果要与另外一个进程的Service进行通信,则可以用Messenger。
其实实现IPC(Inter-Process Communication,进程间通信)的方式,还有AIDL,但推荐使用Messenger,有两点好处:
1. 使用Messenger方式比使用AIDL的方式,实现起来要简单很多
2. 使用Messenger时,所有从Activity传过来的消息都会排在一个队列里,不会同时请求Service,所以是线程安全的。如果你的程序就是要多线程去访问Service,就可以用AIDL,不然最好使用Messenger的方式。
不过,其实Messenger底层用的就是AIDL实现的,看一下实现方式,先看Service的代码:
1.public class MessengerService extends Service { 2. /** 用于Handler里的消息类型 */ 3. static final int MSG_SAY_HELLO = 1; 4. 5. /** 6. * 在Service处理Activity传过来消息的Handler 7. */ 8. class IncomingHandler extends Handler { 9. @Override 10. public void handleMessage(Message msg) { 11. switch (msg.what) { 12. case MSG_SAY_HELLO: 13. Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show(); 14. break; 15. default: 16. super.handleMessage(msg); 17. } 18. } 19. } 20. 21. /** 22. * 这个Messenger可以关联到Service里的Handler,Activity用这个对象发送Message给Service,Service通过Handler进行处理。 23. */ 24. final Messenger mMessenger = new Messenger(new IncomingHandler()); 25. 26. /** 27. * 当Activity绑定Service的时候,通过这个方法返回一个IBinder,Activity用这个IBinder创建出的Messenger,就可以与Service的Handler进行通信了 28. */ 29. @Override 30. public IBinder onBind(Intent intent) { 31. Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show(); 32. return mMessenger.getBinder(); 33. } 34.}
再看一下Activity的代码:
1.public class ActivityMessenger extends Activity { 2. /** 向Service发送Message的Messenger对象 */ 3. Messenger mService = null; 4. 5. /** 判断有没有绑定Service */ 6. boolean mBound; 7. 8. private ServiceConnection mConnection = new ServiceConnection() { 9. public void onServiceConnected(ComponentName className, IBinder service) { 10. // Activity已经绑定了Service 11. // 通过参数service来创建Messenger对象,这个对象可以向Service发送Message,与Service进行通信 12. mService = new Messenger(service); 13. mBound = true; 14. } 15. 16. public void onServiceDisconnected(ComponentName className) { 17. mService = null; 18. mBound = false; 19. } 20. }; 21. 22. public void sayHello(View v) { 23. if (!mBound) return; 24. // 向Service发送一个Message 25. Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0); 26. try { 27. mService.send(msg); 28. } catch (RemoteException e) { 29. e.printStackTrace(); 30. } 31. } 32. 33. @Override 34. protected void onCreate(Bundle savedInstanceState) { 35. super.onCreate(savedInstanceState); 36. setContentView(R.layout.main); 37. } 38. 39. @Override 40. protected void onStart() { 41. super.onStart(); 42. // 绑定Service 43. bindService(new Intent(this, MessengerService.class), mConnection, 44. Context.BIND_AUTO_CREATE); 45. } 46. 47. @Override 48. protected void onStop() { 49. super.onStop(); 50. // 解绑 51. if (mBound) { 52. unbindService(mConnection); 53. mBound = false; 54. } 55. } 56.}
注意:以上写的代码只能实现从Activity向Service发送消息,如果想从Service向Activity发送消息,只要把代码反过来写就可以了。
使用AIDL
AIDL,Android Interface Definition Language。建立AIDL服务要比建立普通的服务复杂一些,具体步骤如下:
(1)在Eclipse Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同。详细介绍见实例的内容。
(2)如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)。
(3)建立一个服务类(Service的子类)。
(4)实现由aidl文件生成的Java接口。
(5)在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。