binder机制是贯穿整个​​Android​​系统的进程间访问机制,经常被用来访问service,我们结合代码看一下binder在访问service的情形下是怎么具体使用的。


service 你可以理解成没有的界面的activity,它是跑在后台的程序,所谓后台是相对于可以被看得到的程序的,后台程序是不能直接交互的程序。

binder主要是用来进程间通信的,但也可用在和本地service通信。


1. 我们先来看一个与本地service通信的例子。


[java] 
​​ view plain​​
​​ copy​​
​​ print​


1. package
2.
3. import
4. import
5. import
6. import
7. import
8. /**
9. * This is a service stub for both LocalBinderClient
10. * and RemoteBinderClient
11. * @author Wang Xin
12. * @email springnap@163.com
13. *
14. */
15. public class LocalService extends
16.
17. @Override
18. public
19. return new
20. }
21.
22. public void
23. this.getApplicationContext(), "Hello World Local Service!", Toast.LENGTH_SHORT).show();
24. }
25.
26. public class LocalBinder extends
27. LocalService getService() {
28. // Return this instance of LocalService so clients can call public methods
29. return LocalService.this;
30. }
31. }
32. }


local servcie 的代码如上,在onBinder方法中返回binder,binder包含了service的句柄,客户端得到句柄以后就可以调用servcie的公共方法了,这种调用方式是最常见的。


客户端代码


[java] 
​​ view plain​​
​​ copy​​
​​ print​​
​​​


1. package
2.
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11.
12. import
13.
14. public class LocalServiceTestActivity extends
15. static final String TAG = "LocalBinderTestActivity";
16. ServiceConnection mSc;
17.
18. /** Called when the activity is first created. */
19. @Override
20. public void
21. super.onCreate(savedInstanceState);
22. setContentView(R.layout.main);
23.
24. new
25. @Override
26. public void
27. "service connected");
28. LocalService ss = ((LocalBinder)service).getService();
29. ss.sayHelloWorld();
30. }
31.
32. @Override
33. public void
34. "service disconnected");
35. }
36. };
37. }
38.
39. @Override
40. protected void
41. super.onStart();
42. this.getApplicationContext().getPackageCodePath());
43. new Intent(this.getApplicationContext(),LocalService.class);
44. this.bindService(service, mSc, Context.BIND_AUTO_CREATE);
45. }
46.
47. @Override
48. protected void
49. super.onStop();
50. //must unbind the service otherwise the ServiceConnection will be leaked.
51. this.unbindService(mSc);
52. }
53. }


需要注意的是在onStop中要解绑定service, 否则会造成内存泄露的问题。


2. 我们再看一下与另外一个进程中的service进行通信的问题(跨进程通信!)。

如何将servcie运行在另外一个进程呢?在manifest 里面配置个属性就行了。

android:process=":remote" , 代表这个service运行在同一个应用程序的不同进程中。


客户端可以使用Messenger发送消息到service。

[html] 
​​ view plain​​
​​ copy​​
​​ prin​


1. <?xml version="1.0" encoding="utf-8"?>
2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3. package="com.ckt.wangxin"
4. android:versionCode="1"
5. android:versionName="1.0" >
6.
7. <uses-sdk android:minSdkVersion="15" />
8.
9. <application
10. android:icon="@drawable/ic_launcher"
11. android:label="@string/app_name" >
12. <activity
13. android:name=".LocalServiceTestActivity"
14. android:label="@string/app_name" >
15. <intent-filter>
16. <action android:name="android.intent.action.MAIN" />
17. <category android:name="android.intent.category.LAUNCHER" />
18. </intent-filter> -->
19. </activity>
20. <service android:name=".LocalService"></service>
21. android:process=":remote"
22. >
23. <service android:name=".RemoteService" android:process=":remote"></service>
24. <activity android:name="RemoteServiceTestActivity">
25. <intent-filter>
26. <action android:name="android.intent.action.MAIN" />
27. <category android:name="android.intent.category.LAUNCHER" />
28. </intent-filter>
29.
30. </activity>
31. </application>
32.
33. </manifest>

客户端代码:


[java] 
​​ view plain​​
​​ copy​​
​​ prin​


1. package
2.
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. import
13. import
14. import
15. import
16.
17. public class RemoteServiceTestActivity extends
18. static final String TAG = "RemoteServiceTestActivity";
19. ServiceConnection mSc;
20. public static final int SAY_HELLO_TO_CLIENT = 0;
21. /**
22. * Handler of incoming messages from service.
23. */
24. class IncomingHandler extends
25. @Override
26. public void
27. switch
28. case
29. this.getApplicationContext(), "Hello World Remote Client!",
30. Toast.LENGTH_SHORT).show();
31. break;
32. default:
33. super.handleMessage(msg);
34. }
35. }
36. }
37.
38. new Messenger(new
39.
40. /** Called when the activity is first created. */
41. @Override
42. public void
43. super.onCreate(savedInstanceState);
44. setContentView(R.layout.main);
45.
46. new
47. @Override
48. public void
49. "service connected");
50. Messenger messenger = new
51. new
52. msg.what = RemoteService.MSG_SAY_HELLO;
53. msg.replyTo = messenger_reciever;
54. try
55. messenger.send(msg);
56. catch
57. e.printStackTrace();
58. }
59. }
60.
61. @Override
62. public void
63. "service disconnected");
64. }
65. };
66. }
67.
68. @Override
69. protected void
70. super.onStart();
71. this.getApplicationContext().getPackageCodePath());
72. new Intent(this.getApplicationContext(),RemoteService.class);
73. this.bindService(service, mSc, Context.BIND_AUTO_CREATE);
74. }
75.
76. @Override
77. protected void
78. super.onStop();
79. //must unbind the service otherwise the ServiceConnection will be leaked.
80. this.unbindService(mSc);
81. }
82. }


获得service端传来的binder,用来构建一个Messenger向service发送消息。


service端代码:


[java] 
​​ view plain​​
​​ copy​​
​​ prin

1. package
2.
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11.
12. public class RemoteService extends
13.
14. public static final int MSG_SAY_HELLO = 0;
15.
16. @Override
17. public
18. return
19. }
20.
21. new
22.
23. @Override
24. public void
25. if(msg.replyTo != null){
26. this.obtainMessage();
27. msg_client.what = RemoteServiceTestActivity.SAY_HELLO_TO_CLIENT;
28. try
29. ((Messenger)msg.replyTo).send(msg_client);
30. catch
31. // TODO Auto-generated catch block
32. e.printStackTrace();
33. }
34. }
35. switch
36. case
37. this.getApplicationContext(), "Hello World Remote Service!",
38. Toast.LENGTH_SHORT).show();
39. break;
40. default:
41. super.handleMessage(msg);
42. }
43. }
44.
45. };
46.
47. new
48. }

构建一个Messenger,包含一个handler,然后将messenger的binder传给客户端,客户端可以通过handler再构造一个messenger与service通信,消息在handler里面被处理。

现在是service端单向响应客户端的消息,同理可以做成双向发送消息,实现双向通信。