Android IPC 系列(1):Service

来源:互联网 发布:mac系统照片处理软件 编辑:程序博客网 时间:2024/06/03 17:44

原文地址:http://blog.csdn.net/chenfeng0104/article/details/6989178


使用Service的场合:

1.一个或多个Activity需要向同一应用中的Service发出执行某一操作的命令。

PS:不需要绑定

2.某个Activity需要同一应用中的Service为其单独服务,当此Activity消毁时,也将为其服务的Service一并消毁。

PS:需要绑定

3.多个Activity绑定到同一个Service,仅当所有Activity取消了绑定,Service才消毁。

PS:只有第一个Activity绑定时才调用onBind()方法,第二个、第三个....第N个直接取得第一个Activity绑定时onBind()方法返回的IBinder对象

4.即使退出当前应用时,仍希望Service继续运行(如:上传或下载任务);或者此Service为其他应用提供服务。

PS:需要跨进程通信(IPC)

4.1当远程服务不需要支持多线程时,使用Messager.


Server端应用代码

[java] view plaincopyprint?
  1. public class RemoteServiceProxy extends Service {
  2. public static final int GET_RESULT = 1;
  3. private final Messenger> new Messenger(new Handler() {
  4. private int status = 0;
  5. @Override
  6. public void handleMessage(Message msg) {
  7. if (msg.what == GET_RESULT) {
  8. try {
  9. msg.replyTo.send(Message.obtain(null, GET_RESULT, status++, 0));
  10. } catch (RemoteException e) {
  11. e.printStackTrace();
  12. }
  13. } else {
  14. super.handleMessage(msg);
  15. }
  16. }
  17. });

  18. @Override
  19. public IBinder onBind(Intent intent) {
  20. return mMessenger.getBinder();
  21. }
  22. }

[html] view plaincopyprint?
  1. <service android:name=".module.photo.RemoteServiceProxy"
  2. android:process=":remote" />

Client端应用代码


[java] view plaincopyprint?
  1. //开启一个服务
  2. bindService(new Intent(this, RemoteServiceProxy.class), mConnection, BIND_AUTO_CREATE);

  3. private Messenger mService;
  4. private ServiceConnection> new ServiceConnection() {
  5. @Override
  6. public void onServiceConnected(ComponentName> new Messenger(service);
  7. }

  8. @Override
  9. public void onServiceDisconnected(ComponentName name) {
  10. }
  11. };


[java] view plaincopyprint?
  1. private Messenger> new Messenger(new Handler() {
  2. @Override
  3. public void handleMessage(Message msg) {
  4. if (msg.what == RemoteServiceProxy.GET_RESULT) {
  5. Log.i("M", "From Remote Service "+msg.arg1);
  6. } else {
  7. super.handleMessage(msg);
  8. }
  9. }
  10. });

  11. Message message = Message.obtain(null, RemoteServiceProxy.GET_RESULT);
  12. message.replyTo = mMessenger;
  13. try {
  14. mService.send(message);
  15. } catch (RemoteException e) {
  16. e.printStackTrace();
  17. }

4.2当远程服务需要同时响应多个Client的请求,使用AIDL.

注意:一般我们应用中是不需要使用AIDL的,这里仅仅是为了学习和深入理解Android的IPC机制。

Server端应用代码

在Server端应用新建IRemoteService.aidl和IRemoteCallback.aidl文件,编辑内容如下

[java] view plaincopyprint?
  1. package com.example.aidl;

  2. interface IRemoteCallback {
  3. void executeCallback(String msg);
  4. }

[java] view plaincopyprint?
  1. package com.example.aidl;

  2. import com.example.aidl.IRemoteCallback;

  3. interface IRemoteService {
  4. //注册回调
  5. void register(IRemoteCallback callback);
  6. //取消注册回调
  7. void unregister(IRemoteCallback callback);
  8. //执行回调
  9. void execute();
  10. //获取状态
  11. int getStatus(String flag);
  12. }

创建Service类为客户端提供服务
[java] view plaincopyprint?
  1. package com.example.server.service;

  2. import com.example.aidl.IRemoteCallback;
  3. import com.example.aidl.IRemoteService;

  4. import android.app.Service;
  5. import android.content.Intent;
  6. import android.os.IBinder;
  7. import android.os.RemoteCallbackList;
  8. import android.os.RemoteException;
  9. import android.util.Log;

  10. public class RemoteService extends Service {

  11. @Override
  12. public IBinder onBind(Intent intent) {
  13. return iBinder;
  14. }

  15. private final RemoteCallbackList<IRemoteCallback>> new RemoteCallbackList<IRemoteCallback>();

  16. private IRemoteService.Stub> new IRemoteService.Stub() {
  17. @Override
  18. public void register(IRemoteCallback cb) throws RemoteException {
  19. if (cb != null) remoteCallbackList.register(cb);
  20. }

  21. @Override
  22. public void unregister(IRemoteCallback cb) throws RemoteException {
  23. if (cb != null) remoteCallbackList.unregister(cb);
  24. }

  25. @Override
  26. public void execute() throws RemoteException {
  27. int size = remoteCallbackList.beginBroadcast();
  28. while (size > 0) {
  29. size--;
  30. remoteCallbackList.getBroadcastItem(size).executeCallback("Hello, Client.");
  31. }
  32. remoteCallbackList.finishBroadcast();
  33. Log.i("RS", "RemoteService.execute() has done.");
  34. }

  35. int status;
  36. @Override
  37. public int getStatus(String flag) throws RemoteException {
  38. Log.i("RS", "RemoteService.getStatus(flag) flag is "+flag);
  39. if ("reset".equals(flag))> 0;
  40. return status++;
  41. }
  42. };
  43. }

在AndroidManifast.xml中配置Service,必需设置Action过滤

[html] view plaincopyprint?
  1. <service android:name=".server.service.RemoteService" android:process=":remote">
  2. <intent-filter>
  3. <action android:name="test.remote.service"/>
  4. </intent-filter>
  5. </service>

Client端应用代码

将Server端创建的IRemoteService.aidl和IRemoteCallback.aidl文件copy到Client端应用中

在Client端获取Server端的RemoteService对象的引用

[java] view plaincopyprint?
  1. package com.example;

  2. import com.example.aidl.IRemoteCallback;
  3. import com.example.aidl.IRemoteService;

  4. import android.app.Activity;
  5. import android.content.ComponentName;
  6. import android.content.Intent;
  7. import android.content.ServiceConnection;
  8. import android.os.Bundle;
  9. import android.os.IBinder;
  10. import android.os.RemoteException;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Toast;

  14. public class ClientActivity extends Activity {
  15. @Override
  16. public void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.client_activity);

  19. /*
  20. 绑定远程服务,与其他进程Service通信。
  21. 注意:Client需要通过Action与RemoteService绑定,因为Client端是没有RemoteService.class的
  22. */
  23. this.bindService(new Intent("test.remote.service"), sConnection, BIND_AUTO_CREATE);

  24. this.findViewById(R.id.execute_callback).setOnClickListener(mOnClickListener);
  25. this.findViewById(R.id.get_status).setOnClickListener(mOnClickListener);
  26. }

  27. private OnClickListener> new OnClickListener() {
  28. @Override
  29. public void onClick(View button) {
  30. try {
  31. if (button.getId() == R.id.execute_callback) remoteService.execute();
  32. else {
  33. int remoteStatus = remoteService.getStatus("set");
  34. Toast.makeText(getApplicationContext(), "Status: "+remoteStatus+" is from RemoteService", Toast.LENGTH_LONG).show();
  35. }
  36. } catch (RemoteException e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. };

  41. private IRemoteService remoteService;//远程服务
  42. private ServiceConnection> new ServiceConnection() {
  43. @Override
  44. public void onServiceConnected(ComponentName>
  45. //注册回调
  46. try {
  47. remoteService.register(remoteCallback);
  48. } catch (RemoteException e) {
  49. e.printStackTrace();
  50. }
  51. }

  52. @Override
  53. public void onServiceDisconnected(ComponentName name) {
  54. //意外断开连接时回调
  55. remoteService = null;
  56. }
  57. };

  58. private IRemoteCallback.Stub> new IRemoteCallback.Stub() {
  59. @Override
  60. public void executeCallback(String msg) throws RemoteException {
  61. Toast.makeText(getApplicationContext(), "ClientActivity: "+msg, Toast.LENGTH_LONG).show();
  62. }
  63. };
  64. }   
0 0
原创粉丝点击