android 多进程 Binder AIDL Service

本文参考http://blog.csdn.net/saintswordsman/article/details/5130947

android的多进程是通过Binder来实现的,一个类,继承了Binder,那么它的对象就可以被远程的进程使用了(前提是远程进程获取了这个类的对象【对象的引用】,至于如如何获得看下文),怎么使用呢?在Android中, 则采用AIDL(Android InterfaceDefinition Language:接口定义语言)方式实现,所以我们必须写后缀为.aidl的文件。.aidl文件放在src下面,刷新一下就会生成同名的.java文件

文件:forActivity.aidl

[java] view
plain
copy

  1. package com.styleflying.AIDL;
  2. interface forActivity {
  3. void performAction();
  4. }

文件:forService.aidl

[java] view
plain
copy

  1. package com.styleflying.AIDL;
  2. import com.styleflying.AIDL.forActivity;
  3. interface forService {
  4. void registerTestCall(forActivity cb);
  5. void invokCallBack();
  6. }

这两个文件和Java文件放置的地方一样,看包名。

在Eclipse中它们将被自动编译为forActivity.java和forService.java,它们存放在gen目录下。为了方便手头无法演练的读者,代码贴上,不用细看。

文件forActivity.java:

[java] view
plain
copy

  1. /*
  2. * This file is auto-generated.  DO NOT MODIFY.
  3. * Original file: D://workspace//AIDLTest//src//com//styleflying//AIDL//forActivity.aidl
  4. */
  5. package com.styleflying.AIDL;
  6. import java.lang.String;
  7. import android.os.RemoteException;
  8. import android.os.IBinder;
  9. import android.os.IInterface;
  10. import android.os.Binder;
  11. import android.os.Parcel;
  12. public interface forActivity extends android.os.IInterface
  13. {
  14. /** Local-side IPC implementation stub class. */
  15. public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forActivity
  16. {
  17. private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forActivity";
  18. /** Construct the stub at attach it to the interface. */
  19. public Stub()
  20. {
  21. this.attachInterface(this, DESCRIPTOR);
  22. }
  23. /**
  24. * Cast an IBinder object into an forActivity interface,
  25. * generating a proxy if needed.
  26. */
  27. public static com.styleflying.AIDL.forActivity asInterface(android.os.IBinder obj)
  28. {
  29. if ((obj==null)) {
  30. return null;
  31. }
  32. android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
  33. if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forActivity))) {
  34. return ((com.styleflying.AIDL.forActivity)iin);
  35. }
  36. return new com.styleflying.AIDL.forActivity.Stub.Proxy(obj);
  37. }
  38. public android.os.IBinder asBinder()
  39. {
  40. return this;
  41. }
  42. @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
  43. {
  44. switch (code)
  45. {
  46. case INTERFACE_TRANSACTION:
  47. {
  48. reply.writeString(DESCRIPTOR);
  49. return true;
  50. }
  51. case TRANSACTION_performAction:
  52. {
  53. data.enforceInterface(DESCRIPTOR);
  54. this.performAction();
  55. reply.writeNoException();
  56. return true;
  57. }
  58. }
  59. return super.onTransact(code, data, reply, flags);
  60. }
  61. private static class Proxy implements com.styleflying.AIDL.forActivity
  62. {
  63. private android.os.IBinder mRemote;
  64. Proxy(android.os.IBinder remote)
  65. {
  66. mRemote = remote;
  67. }
  68. public android.os.IBinder asBinder()
  69. {
  70. return mRemote;
  71. }
  72. public java.lang.String getInterfaceDescriptor()
  73. {
  74. return DESCRIPTOR;
  75. }
  76. public void performAction() throws android.os.RemoteException
  77. {
  78. android.os.Parcel _data = android.os.Parcel.obtain();
  79. android.os.Parcel _reply = android.os.Parcel.obtain();
  80. try {
  81. _data.writeInterfaceToken(DESCRIPTOR);
  82. mRemote.transact(Stub.TRANSACTION_performAction, _data, _reply, 0);
  83. _reply.readException();
  84. }
  85. finally {
  86. _reply.recycle();
  87. _data.recycle();
  88. }
  89. }
  90. }
  91. static final int TRANSACTION_performAction = (IBinder.FIRST_CALL_TRANSACTION + 0);
  92. }
  93. public void performAction() throws android.os.RemoteException;
  94. }

文件forService.java:

[java] view
plain
copy

  1. /*
  2. * This file is auto-generated.  DO NOT MODIFY.
  3. * Original file: D://workspace//AIDLTest//src//com//styleflying//AIDL//forService.aidl
  4. */
  5. package com.styleflying.AIDL;
  6. import java.lang.String;
  7. import android.os.RemoteException;
  8. import android.os.IBinder;
  9. import android.os.IInterface;
  10. import android.os.Binder;
  11. import android.os.Parcel;
  12. public interface forService extends android.os.IInterface
  13. {
  14. /** Local-side IPC implementation stub class. */
  15. public static abstract class Stub extends android.os.Binder implements com.styleflying.AIDL.forService
  16. {
  17. private static final java.lang.String DESCRIPTOR = "com.styleflying.AIDL.forService";
  18. /** Construct the stub at attach it to the interface. */
  19. public Stub()
  20. {
  21. this.attachInterface(this, DESCRIPTOR);
  22. }
  23. /**
  24. * Cast an IBinder object into an forService interface,
  25. * generating a proxy if needed.
  26. */
  27. public static com.styleflying.AIDL.forService asInterface(android.os.IBinder obj)
  28. {
  29. if ((obj==null)) {
  30. return null;
  31. }
  32. android.os.IInterface iin = (android.os.IInterface)obj.queryLocalInterface(DESCRIPTOR);
  33. if (((iin!=null)&&(iin instanceof com.styleflying.AIDL.forService))) {
  34. return ((com.styleflying.AIDL.forService)iin);
  35. }
  36. return new com.styleflying.AIDL.forService.Stub.Proxy(obj);
  37. }
  38. public android.os.IBinder asBinder()
  39. {
  40. return this;
  41. }
  42. @Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
  43. {
  44. switch (code)
  45. {
  46. case INTERFACE_TRANSACTION:
  47. {
  48. reply.writeString(DESCRIPTOR);
  49. return true;
  50. }
  51. case TRANSACTION_registerTestCall:
  52. {
  53. data.enforceInterface(DESCRIPTOR);
  54. com.styleflying.AIDL.forActivity _arg0;
  55. _arg0 = com.styleflying.AIDL.forActivity.Stub.asInterface(data.readStrongBinder());
  56. this.registerTestCall(_arg0);
  57. reply.writeNoException();
  58. return true;
  59. }
  60. case TRANSACTION_invokCallBack:
  61. {
  62. data.enforceInterface(DESCRIPTOR);
  63. this.invokCallBack();
  64. reply.writeNoException();
  65. return true;
  66. }
  67. }
  68. return super.onTransact(code, data, reply, flags);
  69. }
  70. private static class Proxy implements com.styleflying.AIDL.forService
  71. {
  72. private android.os.IBinder mRemote;
  73. Proxy(android.os.IBinder remote)
  74. {
  75. mRemote = remote;
  76. }
  77. public android.os.IBinder asBinder()
  78. {
  79. return mRemote;
  80. }
  81. public java.lang.String getInterfaceDescriptor()
  82. {
  83. return DESCRIPTOR;
  84. }
  85. public void registerTestCall(com.styleflying.AIDL.forActivity cb) throws android.os.RemoteException
  86. {
  87. android.os.Parcel _data = android.os.Parcel.obtain();
  88. android.os.Parcel _reply = android.os.Parcel.obtain();
  89. try {
  90. _data.writeInterfaceToken(DESCRIPTOR);
  91. _data.writeStrongBinder((((cb!=null))?(cb.asBinder()):(null)));
  92. mRemote.transact(Stub.TRANSACTION_registerTestCall, _data, _reply, 0);
  93. _reply.readException();
  94. }
  95. finally {
  96. _reply.recycle();
  97. _data.recycle();
  98. }
  99. }
  100. public void invokCallBack() throws android.os.RemoteException
  101. {
  102. android.os.Parcel _data = android.os.Parcel.obtain();
  103. android.os.Parcel _reply = android.os.Parcel.obtain();
  104. try {
  105. _data.writeInterfaceToken(DESCRIPTOR);
  106. mRemote.transact(Stub.TRANSACTION_invokCallBack, _data, _reply, 0);
  107. _reply.readException();
  108. }
  109. finally {
  110. _reply.recycle();
  111. _data.recycle();
  112. }
  113. }
  114. }
  115. static final int TRANSACTION_registerTestCall = (IBinder.FIRST_CALL_TRANSACTION + 0);
  116. static final int TRANSACTION_invokCallBack = (IBinder.FIRST_CALL_TRANSACTION + 1);
  117. }
  118. public void registerTestCall(com.styleflying.AIDL.forActivity cb) throws android.os.RemoteException;
  119. public void invokCallBack() throws android.os.RemoteException;
  120. }

我们可以看到在.java文件中都定义了一个抽象类Stub,Stub就是继承Binder。

好了,那我们那里用到了Binder呢?没错,就是Service,Service使用有两种方法,startService,bindeService。bindeService时在实现Service就必须实现 onBind 返回一个Binder对象,这个Binder对象就会被activity回调使用。这样activity跟service就可以通信了。当然是activity可以调用service了。接下来的例子还实现了相互调用。

看mAIDLService.java:

[java] view
plain
copy

  1. package com.styleflying.AIDL;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.os.RemoteCallbackList;
  6. import android.os.RemoteException;
  7. import android.util.Log;
  8. public class mAIDLService extends Service {
  9. private static final String TAG = "AIDLService";
  10. private forActivity callback;
  11. private void Log(String str) {
  12. Log.d(TAG, "------ " + str + "------");
  13. }
  14. @Override
  15. public void onCreate() {
  16. Log("service create");
  17. }
  18. @Override
  19. public void onStart(Intent intent, int startId) {
  20. Log("service start id=" + startId);
  21. }
  22. @Override
  23. public IBinder onBind(Intent t) {
  24. Log("service on bind");
  25. return mBinder;
  26. }
  27. @Override
  28. public void onDestroy() {
  29. Log("service on destroy");
  30. super.onDestroy();
  31. }
  32. @Override
  33. public boolean onUnbind(Intent intent) {
  34. Log("service on unbind");
  35. return super.onUnbind(intent);
  36. }
  37. public void onRebind(Intent intent) {
  38. Log("service on rebind");
  39. super.onRebind(intent);
  40. }
  41. private final forService.Stub mBinder = new forService.Stub() {
  42. @Override
  43. public void invokCallBack() throws RemoteException
  44. {
  45. callback.performAction();
  46. }
  47. @Override
  48. public void registerTestCall(forActivity cb) throws RemoteException
  49. {
  50. callback = cb;
  51. }
  52. };
  53. }

其中mBinder就是给activity调用了。然而这个类中的mBinder 中的registerTestCall传递的forActivity就是能service调用activity用的。

看mAIDLActivity.java:

[java] view
plain
copy

  1. package com.styleflying.AIDL;
  2. import android.app.Activity;
  3. import android.content.ComponentName;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.content.ServiceConnection;
  7. import android.os.Bundle;
  8. import android.os.IBinder;
  9. import android.os.RemoteException;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.Toast;
  15. public class mAIDLActivity extends Activity {
  16. private static final String TAG = "AIDLActivity";
  17. private Button btnOk;
  18. private Button btnCancel;
  19. private Button btnCallBack;
  20. private void Log(String str) {
  21. Log.d(TAG, "------ " + str + "------");
  22. }
  23. private forActivity mCallback = new forActivity.Stub() {
  24. public void performAction() throws RemoteException
  25. {
  26. Toast.makeText(mAIDLActivity.this, "this toast is called from service", 1).show();
  27. }
  28. };
  29. forService mService;
  30. private ServiceConnection mConnection = new ServiceConnection() {
  31. public void onServiceConnected(ComponentName className,
  32. IBinder service) {
  33. mService = forService.Stub.asInterface(service);
  34. try {
  35. mService.registerTestCall(mCallback);}
  36. catch (RemoteException e) {
  37. }
  38. }
  39. public void onServiceDisconnected(ComponentName className) {
  40. Log("disconnect service");
  41. mService = null;
  42. }
  43. };
  44. @Override
  45. public void onCreate(Bundle icicle) {
  46. super.onCreate(icicle);
  47. setContentView(R.layout.main);
  48. btnOk = (Button)findViewById(R.id.btn_ok);
  49. btnCancel = (Button)findViewById(R.id.btn_cancel);
  50. btnCallBack = (Button)findViewById(R.id.btn_callback);
  51. btnOk.setOnClickListener(new OnClickListener() {
  52. public void onClick(View v) {
  53. Bundle args = new Bundle();
  54. Intent intent = new Intent(mAIDLActivity.this, mAIDLService.class);
  55. intent.putExtras(args);
  56. bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
  57. startService(intent);
  58. }
  59. });
  60. btnCancel.setOnClickListener(new OnClickListener() {
  61. public void onClick(View v) {
  62. unbindService(mConnection);
  63. //stopService(intent);
  64. }
  65. });
  66. btnCallBack.setOnClickListener(new OnClickListener() {
  67. @Override
  68. public void onClick(View v)
  69. {
  70. try
  71. {
  72. mService.invokCallBack();
  73. } catch (RemoteException e)
  74. {
  75. // TODO Auto-generated catch block
  76. e.printStackTrace();
  77. }
  78. }
  79. });
  80. }
  81. }

其中按钮点击bindeService时就会触发ServiceConnection,返回了mService = forService.Stub.asInterface(service); activity跟service实现了通信,再mService.registerTestCall(mCallback);} 这样service跟activity又能通信了。在mService.invokCallBack();顺序是activity->service->activity

还有几篇android多进程通信写得不错一并贴出来

http://www.cnblogs.com/BeyondAnyTime/p/3204119.html

http://www.apkbus.com/android-83462-1-1.html

http://blog.csdn.net/baodinglaolang/article/details/9903499

时间: 2025-01-02 00:14:49

android 多进程 Binder AIDL Service的相关文章

android 怎样用AIDL Service 传递复杂数据

大家都知道在Android中通过AIDL可以跨进程调用Service中的数据,网上也有很多实例,但是大部分实例都是关于基本数据类型的远程调用,很少讲到复杂数据的调用,今天我用一个例子来演示一下怎样用AIDL Service 传递复杂数据. 我们分2步开始: 第一步:部署我们的服务端,也就是Service端: 1:在Service端我先自定义2个类型:Person和Pet.因为我们需要跨进程传递Person对象和Pet对象,所以Person类和Pet类都必须实现Parcelable接口,并要求在实

Android 使用binder访问service的方式

binder机制是贯穿整个Android系统的进程间访问机制,经常被用来访问service,我们结合代码看一下binder在访问service的情形下是怎么具体使用的. service 你可以理解成没有的界面的activity,它是跑在后台的程序,所谓后台是相对于可以被看得到的程序的,后台程序是不能直接交互的程序. binder主要是用来进程间通信的,但也可用在和本地service通信. 1. 我们先来看一个与本地service通信的例子. package com.ckt.wangxin; im

Android中的跨进程通信方法实例及特点分析(一):AIDL Service

转载请注明出处:http://blog.csdn.net/bettarwang/article/details/40947481 最近有一个需求就是往程序中加入大数据的采集点,但是因为我们的Android程序包含两个进程,所以涉及到跨进程通信的问题.现将Android中的跨进程通信方式总结如下. Android中有4种跨进程通信方式,分别是利用AIDL Service.ContentProvider.Broadcast.Activity实现. 1.利用AIDL Service实现跨进程通信 这是

Android学习笔记二十六.跨进程调用Service(AIDL Service)

跨进程调用Service(AIDL Service) 一.AIDL Service 1.什么是AIDL Service? AIDL,即Android Interface Definition Language.是Android用于定义远程接口,AIDL接口定义语言的语法比较简单,这种接口定义语言并不是真正的编程语言,它只是定义两个进程之间的通信接口.AIDL的语法与Java接口很相似,但存在如下几点差异: (1)AIDL定义接口的源代码必须以.aidl结尾; (2)AIDL接口中用到数据类型,除

跨进程调用Service(AIDL Service)

1.什么是aidl:aidl是 Android Interface definition language的缩写,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口 icp:interprocess communication :内部进程通信 2.既然aidl可以定义并实现进程通信,那么我们怎么使用它呢?文档/android-sdk/docs/guide/developing/tools/aidl.html中对步骤作了详细描述: --1.Create

Android中的AIDL Android studio中建aidl

1.aidl: android interface definition language,是一种它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口icp:interprocess communication :内部进程通信 2.既然aidl可以定义并实现进程通信,那么我们怎么使用它呢?文档/android-sdk/docs/guide/developing/tools/aidl.html中对步骤作了详细描述: --1.Create your .aidl fil

Abdroid---44---使用AIDL Service 实现跨进程调用Service

 为了实现跨进程通信(interprocess communication 简称 IPC),Android提供了AIDL Service. AIDL 是一种IDL语言,用于生成可以在Android设备上两个进程之间进行通信的代码 如果在一个进程中药调用另一个进程中对象的操作,就可以使用AIDL生成可序列化的参数. AIDL是面向接口的 与绑定本地Service不同的是,本地Service的onBind方法会直接把IBinder对象本身传给客户端的ServiceConnection 的onSe

Android service binder aidl 关系

/********************************************************************************** * Android service binder aidl 关系 * 声明: * 最近一直被Android中的service.binder.aidl这三者之间的关系给搞得有点难受, * 于是就自己花了点时间,将他们之间的关系给画出来,这样思维上就清晰多了,也方便 * 和朋友沟通,减少沟通成本. * * 2016-1-10 晴 深圳

android学习之remote service 的aidl详解

写在前面的话: 关于remote service中使用aidl来实现跨进程,多线程通信,我是参考了三篇文章,大概把这个弄明白了. (1)android 官方关于aidl的说明文档 docs/guide/components/aidl.html (2)Android学习笔记23服务Service之AIDL和远程服务实现进程通信以及进程间传递自定义类型参数 http://blog.csdn.net/honeybaby201314/article/details/19989455 (3) Androi