综述

  IPC(interprocess communication)是指进程间通信,也就是在两个进程间进行数据交互。不同的操作系统都有他们自己的一套IPC机制。例如在Linux操作系统中可以通过管道、信号量、消息队列、内存共享、套接字等进行进程间通信。那么在Android系统中我们可以通过Binder来进行进程间的通信。当然除了Binder我们还可以使用Socket来进行进程间的通信。 
  既然需要进程通信,那么就必须有多个进程。当然,在两个应用交互中必然出现多进程的情况。若是在一个应用中呢?我们可以通过给四大组件在AndroidMenifest中为他们指定android:process属性来实现不同的组件在不同进程中运行。下面就来介绍一下Android中进程间通信的实现方式。

AIDL简介

  AIDL是 Android Interface Definition Language的缩写。AIDL 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行 IPC的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。 
  AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。

AIDL用法

  首先我们创建一个AIDL文件,在AndroidStudio中当我们创建一个AIDL文件时会自动为我们创件一个AILD文件夹,用于存放AIDL文件。创建完之后重新rebuild会自动生成aidl实现类。 
   
  在下面的例子当中,我们将Service单独作为一个应用在系统中运行,在另一个用于访问Service的client也单独作为一个应用运行在系统中。这样保证了两个程序分别运行在两个进程中。并且使用了butterknife进行控件绑定。

AIDL简单用法

演示

  在Service中我们对客户端传来的两个整数做了一次加法运算并返回到客户端中。 
 
  

AIDL代码

  1. // ICalculate.aidl
  2. package com.ljd.aidl;
  3. // Declare any non-default types here with import statements
  4. interface ICalculate {
  5. /**
  6. * Demonstrates some basic types that you can use as parameters
  7. * and return values in AIDL.
  8. */
  9. int add(int first, int second);
  10. }

服务端代码

  1. package com.ljd.aidl.service;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.Binder;
  5. import android.os.IBinder;
  6. import android.os.RemoteException;
  7. import com.ljd.aidl.ICalculate;
  8. public class CalculateService extends Service {
  9. public CalculateService() {
  10. }
  11. private Binder mBinder = new ICalculate.Stub(){
  12. @Override
  13. public int add(int first, int second) throws RemoteException {
  14. return first + second;
  15. }
  16. };
  17. @Override
  18. public IBinder onBind(Intent intent) {
  19. return mBinder;
  20. }
  21. }

客户端代码

  1. package com.ljd.aidl.activity;
  2. import android.content.ComponentName;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.content.ServiceConnection;
  6. import android.os.Bundle;
  7. import android.os.IBinder;
  8. import android.os.RemoteException;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13. import com.ljd.aidl.ICalculate;
  14. import com.ljd.aidl.client.R;
  15. import butterknife.ButterKnife;
  16. import butterknife.OnClick;
  17. public class Demo1Activity extends AppCompatActivity {
  18. private final String TAG = "DEMO1";
  19. //是否已经绑定service
  20. private boolean mIsBindService;
  21. private ICalculate mCalculate;
  22. private ServiceConnection mConnection = new ServiceConnection() {
  23. @Override
  24. public void onServiceConnected(ComponentName name, IBinder service) {
  25. Log.d(TAG,"bind success");
  26. Toast.makeText(Demo1Activity.this,"bind service success",Toast.LENGTH_SHORT).show();
  27. mCalculate = ICalculate.Stub.asInterface(service);
  28. }
  29. @Override
  30. public void onServiceDisconnected(ComponentName name) {
  31. //重新绑定Service防止系统将服务进程杀死而产生的调用错误。
  32. bindService();
  33. }
  34. };
  35. @Override
  36. protected void onCreate(Bundle savedInstanceState) {
  37. super.onCreate(savedInstanceState);
  38. setContentView(R.layout.activity_demo1);
  39. ButterKnife.bind(this);
  40. mIsBindService = false;
  41. }
  42. @Override
  43. protected void onDestroy() {
  44. unbindService();
  45. ButterKnife.unbind(this);
  46. super.onDestroy();
  47. }
  48. @OnClick({ R.id.bind_demo1_btn,R.id.unbind_demo1_btn,R.id.calculate_btn})
  49. public void onClickButton(View v) {
  50. switch (v.getId()){
  51. case R.id.bind_demo1_btn:
  52. bindService();
  53. break;
  54. case R.id.unbind_demo1_btn:
  55. Toast.makeText(this,"unbind service success",Toast.LENGTH_SHORT).show();
  56. unbindService();
  57. break;
  58. case R.id.calculate_btn:
  59. if (mIsBindService && mCalculate != null ){
  60. try {
  61. int result = mCalculate.add(2,4);
  62. Log.d(TAG,String.valueOf(result));
  63. Toast.makeText(this,String.valueOf(result),Toast.LENGTH_SHORT).show();
  64. } catch (RemoteException e) {
  65. e.printStackTrace();
  66. }
  67. } else {
  68. Toast.makeText(this,"not bind service",Toast.LENGTH_SHORT).show();
  69. }
  70. break;
  71. }
  72. }
  73. private void bindService(){
  74. Intent intent = new Intent();
  75. intent.setAction("com.ljd.aidl.action.CALCULATE_SERVICE");
  76. bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
  77. mIsBindService = true;
  78. }
  79. private void unbindService(){
  80. if(mIsBindService){
  81. mIsBindService = false;
  82. unbindService(mConnection);
  83. }
  84. }
  85. }

AIDL高级用法

  对于上面的例子,在AIDL接口中只是使用了一些Java的基本类型,对于AIDL文件并不是所有的类型都是可用的,那么在AIDL中究竟有哪些类型可以使用呢?

AIDL语法规则

默认情况下AIDL支持以下数据类型:

  • 所有Java的基本数据类型(例如: int, long,double, char, boolean等)
  • String和CharSequence
  • List:AIDL实际接收到的是ArrayList,并且List里面所有元素都必须被AIDL支持
  • Map: AIDL实际接收到的是HashMap,并且Map里面所有元素都必须被AIDL支持

如果不是上面所述类型,我们必须要显示import进来,即使他们在同一个包中。当我们使用自定义的对象时必须实现Parcelable接口,Parcelable为对象序列化接口,效率比实现Serializable接口高。并且新建一个与该类同名的AIDL文件,声明他为Parcelable类型。

我们定义AIDL接口还需要注意以下几点:

  • 方法可以有多个或没有参数,可以有返回值也可以为void
  • 在参数中,除了基本类型以外,我们必须为参数标上方向in, out, 或者 inout
  • 在AIDL文件中只支持方法,不支持静态常量

演示

  在计算机商店中需要采购笔记本进行销售,在服务端中我们添加两台笔记本,在客户端中我们为商店加购一台dell笔记本。 
 
  

实体类代码

  我们首先构建一个计算机实体类,包含笔记本的id,品牌,型号,并且实现Parcelable接口,在AndroidStudio中会为我们自动构造代码。 
  

  1. package com.ljd.aidl.entity;
  2. import android.os.Parcel;
  3. import android.os.Parcelable;
  4. public class ComputerEntity implements Parcelable{
  5. public int computerId; //id
  6. public String brand; //品牌
  7. public String model; //型号
  8. public ComputerEntity(int computerId, String brand, String model) {
  9. this.brand = brand;
  10. this.computerId = computerId;
  11. this.model = model;
  12. }
  13. protected ComputerEntity(Parcel in) {
  14. computerId = in.readInt();
  15. brand = in.readString();
  16. model = in.readString();
  17. }
  18. public static final Creator<ComputerEntity> CREATOR = new Creator<ComputerEntity>() {
  19. @Override
  20. public ComputerEntity createFromParcel(Parcel in) {
  21. return new ComputerEntity(in);
  22. }
  23. @Override
  24. public ComputerEntity[] newArray(int size) {
  25. return new ComputerEntity[size];
  26. }
  27. };
  28. @Override
  29. public int describeContents() {
  30. return 0;
  31. }
  32. @Override
  33. public void writeToParcel(Parcel dest, int flags) {
  34. dest.writeInt(computerId);
  35. dest.writeString(brand);
  36. dest.writeString(model);
  37. }
  38. }

AIDL代码

  在AIDL中对实体类进行声明,包名和文件名必须与实体类一致。在AndroidStudio中新建一个与实体类同名的AIDL文件会报错,需要先用一个其它名字,然后修改与实体类名一致即可。

  1. package com.ljd.aidl.entity;
  2. //包名必须和对用实体类的包名一致
  3. // Declare any non-default types here with import statements
  4. parcelable ComputerEntity;

  添加两个接口分别为添加一台笔记本和获取全部笔记本,在该文件中使用到了ComputerEntity类,显示的import进来。

  1. package com.ljd.aidl;
  2. import com.ljd.aidl.entity.ComputerEntity;
  3. // Declare any non-default types here with import statements
  4. interface IComputerManager {
  5. /**
  6. * Demonstrates some basic types that you can use as parameters
  7. * and return values in AIDL.
  8. */
  9. void addComputer(in ComputerEntity computer);
  10. List<ComputerEntity> getComputerList();
  11. }

服务端代码

  1. package com.ljd.aidl.service;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.os.RemoteException;
  6. import com.ljd.aidl.IComputerManager;
  7. import com.ljd.aidl.entity.ComputerEntity;
  8. import java.util.List;
  9. import java.util.concurrent.CopyOnWriteArrayList;
  10. public class ComputerService extends Service {
  11. private CopyOnWriteArrayList<ComputerEntity> mComputerList = new CopyOnWriteArrayList<>();
  12. public ComputerService() {
  13. }
  14. private final IComputerManager.Stub mBinder = new IComputerManager.Stub() {
  15. @Override
  16. public void addComputer(ComputerEntity computer) throws RemoteException {
  17. mComputerList.add(computer);
  18. }
  19. @Override
  20. public List<ComputerEntity> getComputerList() throws RemoteException {
  21. return mComputerList;
  22. }
  23. };
  24. @Override
  25. public void onCreate() {
  26. super.onCreate();
  27. mComputerList.add(new ComputerEntity(0,"apple","macbookpro"));
  28. mComputerList.add(new ComputerEntity(1,"microsoft","surfacebook"));
  29. mComputerList.add(new ComputerEntity(2,"dell","XPS13"));
  30. }
  31. @Override
  32. public IBinder onBind(Intent intent) {
  33. return mBinder;
  34. }
  35. }

  注意:在该类中使用了CopyOnWriteArrayList,CopyOnWriteArrayList能够自动进行线程同步。可是在AIDL中接收和返回的只能是ArrayList,其实AIDL支持的是抽象的List,在Binder中会按照List访问数据并最终形成一个ArrayList,所以在AIDL中返回的还是一个ArrayList。

客户端代码

  1. package com.ljd.aidl.activity;
  2. import android.content.ComponentName;
  3. import android.content.Context;
  4. import android.content.Intent;
  5. import android.content.ServiceConnection;
  6. import android.os.IBinder;
  7. import android.os.RemoteException;
  8. import android.support.v7.app.AppCompatActivity;
  9. import android.os.Bundle;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.LinearLayout;
  13. import android.widget.TextView;
  14. import android.widget.Toast;
  15. import com.ljd.aidl.IComputerManager;
  16. import com.ljd.aidl.client.R;
  17. import com.ljd.aidl.entity.ComputerEntity;
  18. import java.util.List;
  19. import butterknife.Bind;
  20. import butterknife.ButterKnife;
  21. import butterknife.OnClick;
  22. public class Demo2Activity extends AppCompatActivity{
  23. @Bind(R.id.show_linear)
  24. LinearLayout mShowLinear;
  25. private boolean mIsBindService;
  26. private IComputerManager mRemoteComputerManager;
  27. private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
  28. @Override
  29. public void binderDied() {
  30. if(mRemoteComputerManager != null){
  31. mRemoteComputerManager.asBinder().unlinkToDeath(mDeathRecipient,0);
  32. mRemoteComputerManager = null;
  33. bindService();
  34. }
  35. }
  36. };
  37. private ServiceConnection mConnection = new ServiceConnection() {
  38. @Override
  39. public void onServiceConnected(ComponentName name, IBinder service) {
  40. mIsBindService = true;
  41. Toast.makeText(Demo2Activity.this,"bind service success",Toast.LENGTH_SHORT).show();
  42. mRemoteComputerManager = IComputerManager.Stub.asInterface(service);
  43. try {
  44. mRemoteComputerManager.asBinder().linkToDeath(mDeathRecipient,0);
  45. } catch (RemoteException e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. @Override
  50. public void onServiceDisconnected(ComponentName name) {
  51. mRemoteComputerManager = null;
  52. }
  53. };
  54. @Override
  55. protected void onCreate(Bundle savedInstanceState) {
  56. super.onCreate(savedInstanceState);
  57. setContentView(R.layout.activity_demo2);
  58. ButterKnife.bind(this);
  59. mIsBindService = false;
  60. }
  61. @Override
  62. protected void onDestroy() {
  63. unbindService();
  64. ButterKnife.unbind(this);
  65. super.onDestroy();
  66. }
  67. @OnClick({R.id.bind_demo2_btn,R.id.unbind_demo2_btn,R.id.test_demo2_btn,R.id.clear_demo2_btn})
  68. public void onClickButton(View v) {
  69. switch (v.getId()){
  70. case R.id.bind_demo2_btn:
  71. bindService();
  72. break;
  73. case R.id.unbind_demo2_btn:
  74. Toast.makeText(this,"unbind service success",Toast.LENGTH_SHORT).show();
  75. unbindService();
  76. break;
  77. case R.id.test_demo2_btn:
  78. if (!mIsBindService || mRemoteComputerManager == null){
  79. Toast.makeText(this,"not bind service",Toast.LENGTH_SHORT).show();
  80. return;
  81. }
  82. try {
  83. List<ComputerEntity> computerList = mRemoteComputerManager.getComputerList();
  84. for (int i =0;i<computerList.size();i++){
  85. String str = "computerId:" + String.valueOf(computerList.get(i).computerId) +
  86. " brand:" + computerList.get(i).brand +
  87. " model:" + computerList.get(i).model ;
  88. TextView textView = new TextView(this);
  89. textView.setText(str);
  90. mShowLinear.addView(textView);
  91. }
  92. } catch (RemoteException e) {
  93. e.printStackTrace();
  94. }
  95. break;
  96. case R.id.clear_demo2_btn:
  97. mShowLinear.removeAllViews();
  98. break;
  99. }
  100. }
  101. private void bindService(){
  102. Intent intent = new Intent();
  103. intent.setAction("com.ljd.aidl.action.COMPUTER_SERVICE");
  104. mIsBindService = bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
  105. }
  106. private void unbindService(){
  107. if(!mIsBindService){
  108. return;
  109. }
  110. mIsBindService = false;
  111. unbindService(mConnection);
  112. }
  113. }

  由于Binder是有可能会意外死亡的,也就是Service所在进程被系统杀死,这时候我们调用Service的方法就会失败。在第一个例子中我们通过onServiceDisconnected方法中重新绑定服务。在这个例子中我们采用了另外一种方法,由于在Binder中提供了两个配对的方法linkToDeath和unlinkToDeath,通过linkToDeath可以给Binder设置一个死亡代理,Binder死亡时回调binderDied方法,在binderDied方法中我们重新绑定服务即可。

AIDL用法拓展

  当我们需要一种笔记本的时候,由于商店缺货,这时候我们会给卖家说一声,我所需要的这款笔记本到货后通知我。也就成了所谓的观察者模式。 
  在Android系统中为我们提供了一个RemoteCallbackList,RemoteCallbackList是系统专门用来删除跨进程的listener接口,并且在RemoteCallbackList中自动实现了线程同步功能,下面看一下它的用法。

演示

  客户端注册服务以后,服务端每隔三秒会添加一台笔记本,并通知给客户端显示。 

AIDL代码

  到货后的AIDL监听接口 
  

  1. package com.ljd.aidl;
  2. import com.ljd.aidl.entity.ComputerEntity;
  3. // Declare any non-default types here with import statements
  4. interface IOnComputerArrivedListener {
  5. /**
  6. * Demonstrates some basic types that you can use as parameters
  7. * and return values in AIDL.
  8. */
  9. void onComputerArrived(in ComputerEntity computer);
  10. }

  在IComputerManager接口中添加两个方法。显示importIOnComputerArrivedListener ,即使在同一个包下面。 
  

  1. // IComputerManagerObserver.aidl
  2. package com.ljd.aidl;
  3. import com.ljd.aidl.entity.ComputerEntity;
  4. import com.ljd.aidl.IOnComputerArrivedListener;
  5. // Declare any non-default types here with import statements
  6. interface IComputerManagerObserver {
  7. /**
  8. * Demonstrates some basic types that you can use as parameters
  9. * and return values in AIDL.
  10. */
  11. void addComputer(in ComputerEntity computer);
  12. List<ComputerEntity> getComputerList();
  13. void registerUser(IOnComputerArrivedListener listener);
  14. void unRegisterUser(IOnComputerArrivedListener listener);
  15. }

服务端代码

  1. import android.app.Service;
  2. import android.content.Intent;
  3. import android.os.Binder;
  4. import android.os.IBinder;
  5. import android.os.RemoteCallbackList;
  6. import android.os.RemoteException;
  7. import com.ljd.aidl.IComputerManagerObserver;
  8. import com.ljd.aidl.IOnComputerArrivedListener;
  9. import com.ljd.aidl.entity.ComputerEntity;
  10. import java.util.List;
  11. import java.util.concurrent.CopyOnWriteArrayList;
  12. import java.util.concurrent.atomic.AtomicBoolean;
  13. public class ComputerObserverService extends Service{
  14. public ComputerObserverService() {
  15. }
  16. private CopyOnWriteArrayList<ComputerEntity> mComputerList = new CopyOnWriteArrayList<>();
  17. private RemoteCallbackList<IOnComputerArrivedListener> mComputerArrivedListenerList = new RemoteCallbackList<>();
  18. private AtomicBoolean mIsServiceDestroy = new AtomicBoolean(false);
  19. private Binder mBinder = new IComputerManagerObserver.Stub(){
  20. @Override
  21. public void addComputer(ComputerEntity computer) throws RemoteException {
  22. mComputerList.add(computer);
  23. }
  24. @Override
  25. public List<ComputerEntity> getComputerList() throws RemoteException {
  26. return mComputerList;
  27. }
  28. @Override
  29. public void registerUser(IOnComputerArrivedListener listener) throws RemoteException {
  30. mComputerArrivedListenerList.register(listener);
  31. }
  32. @Override
  33. public void unRegisterUser(IOnComputerArrivedListener listener) throws RemoteException {
  34. mComputerArrivedListenerList.unregister(listener);
  35. }
  36. };
  37. @Override
  38. public void onCreate() {
  39. super.onCreate();
  40. mComputerList.add(new ComputerEntity(0,"apple","macbookpro"));
  41. mComputerList.add(new ComputerEntity(1,"microsoft","surfacebook"));
  42. mComputerList.add(new ComputerEntity(2,"dell","XPS13"));
  43. new Thread(new Runnable() {
  44. @Override
  45. public void run() {
  46. while (!mIsServiceDestroy.get()){
  47. try {
  48. Thread.currentThread().sleep(3000);
  49. ComputerEntity computer = new ComputerEntity(mComputerList.size(),"******","******");
  50. mComputerList.add(computer);
  51. final int COUNT = mComputerArrivedListenerList.beginBroadcast();
  52. //通知所有注册过的用户
  53. for (int i=0;i<COUNT;i++){
  54. IOnComputerArrivedListener listener = mComputerArrivedListenerList.getBroadcastItem(i);
  55. if (listener != null){
  56. listener.onComputerArrived(computer);
  57. }
  58. }
  59. mComputerArrivedListenerList.finishBroadcast();
  60. } catch (InterruptedException e) {
  61. e.printStackTrace();
  62. } catch (RemoteException e) {
  63. e.printStackTrace();
  64. }
  65. }
  66. }
  67. }).start();
  68. }
  69. @Override
  70. public IBinder onBind(Intent intent) {
  71. return mBinder;
  72. }
  73. @Override
  74. public void onDestroy() {
  75. super.onDestroy();
  76. mIsServiceDestroy.set(true);
  77. }
  78. }

  注意:RemoteCallbackList并不是一个List,所以我们不能像操作List一样操作RemoteCallbackList。并且遍历RemoteCallbackList时,beginBroadcast和finishBroadcast是配对使用的。

客户端代码


  1. import android.content.ComponentName;
  2. import android.content.Context;
  3. import android.content.Intent;
  4. import android.content.ServiceConnection;
  5. import android.os.Handler;
  6. import android.os.IBinder;
  7. import android.os.Message;
  8. import android.os.RemoteException;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.os.Bundle;
  11. import android.view.View;
  12. import android.widget.LinearLayout;
  13. import android.widget.TextView;
  14. import android.widget.Toast;
  15. import com.ljd.aidl.IComputerManagerObserver;
  16. import com.ljd.aidl.IOnComputerArrivedListener;
  17. import com.ljd.aidl.client.R;
  18. import com.ljd.aidl.entity.ComputerEntity;
  19. import java.util.List;
  20. import butterknife.Bind;
  21. import butterknife.ButterKnife;
  22. import butterknife.OnClick;
  23. public class Demo3Activity extends AppCompatActivity {
  24. @Bind(R.id.show_demo3_linear)
  25. LinearLayout mShowLinear;
  26. private boolean mIsBindService;
  27. private static final int MESSAGE_COMPUTER_ARRIVED = 1;
  28. private IComputerManagerObserver mRemoteComputerManager;
  29. private Handler mHandler = new Handler() {
  30. @Override
  31. public void handleMessage(Message msg) {
  32. switch (msg.what){
  33. case MESSAGE_COMPUTER_ARRIVED:
  34. ComputerEntity computer = (ComputerEntity)msg.obj;
  35. String str = "computerId:" + String.valueOf(computer.computerId) +
  36. " brand:" + computer.brand +
  37. " model:" + computer.model ;
  38. TextView textView = new TextView(Demo3Activity.this);
  39. textView.setText(str);
  40. mShowLinear.addView(textView);
  41. break;
  42. default:
  43. super.handleMessage(msg);
  44. break;
  45. }
  46. }
  47. };
  48. private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
  49. @Override
  50. public void binderDied() {
  51. if(mRemoteComputerManager != null){
  52. mRemoteComputerManager.asBinder().unlinkToDeath(mDeathRecipient,0);
  53. mRemoteComputerManager = null;
  54. bindService();
  55. }
  56. }
  57. };
  58. private ServiceConnection mConnection = new ServiceConnection() {
  59. @Override
  60. public void onServiceConnected(ComponentName name, IBinder service) {
  61. mIsBindService = true;
  62. Toast.makeText(Demo3Activity.this,"bind service success",Toast.LENGTH_SHORT).show();
  63. mRemoteComputerManager = IComputerManagerObserver.Stub.asInterface(service);
  64. try {
  65. mRemoteComputerManager.asBinder().linkToDeath(mDeathRecipient,0);
  66. } catch (RemoteException e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. @Override
  71. public void onServiceDisconnected(ComponentName name) {
  72. mRemoteComputerManager = null;
  73. }
  74. };
  75. private IOnComputerArrivedListener mOnComputerArrivedListener = new IOnComputerArrivedListener.Stub(){
  76. @Override
  77. public void onComputerArrived(ComputerEntity computer) throws RemoteException {
  78. mHandler.obtainMessage(MESSAGE_COMPUTER_ARRIVED,computer).sendToTarget();
  79. }
  80. };
  81. @Override
  82. protected void onCreate(Bundle savedInstanceState) {
  83. super.onCreate(savedInstanceState);
  84. setContentView(R.layout.activity_demo3);
  85. ButterKnife.bind(this);
  86. mIsBindService = false;
  87. }
  88. @Override
  89. protected void onDestroy() {
  90. unbindService();
  91. ButterKnife.unbind(this);
  92. super.onDestroy();
  93. }
  94. @OnClick({R.id.bind_demo3_btn,R.id.unbind_demo3_btn,R.id.test_demo3_btn,R.id.clear_demo3_btn})
  95. public void onClickButton(View v){
  96. switch (v.getId()){
  97. case R.id.bind_demo3_btn:
  98. bindService();
  99. break;
  100. case R.id.unbind_demo3_btn:
  101. Toast.makeText(this,"unbind service success",Toast.LENGTH_SHORT).show();
  102. unbindService();
  103. break;
  104. case R.id.test_demo3_btn:
  105. if (!mIsBindService || mRemoteComputerManager == null){
  106. Toast.makeText(this,"not bind service",Toast.LENGTH_SHORT).show();
  107. return;
  108. }
  109. try {
  110. ComputerEntity computer = new ComputerEntity(3,"hp","envy13");
  111. mRemoteComputerManager.addComputer(computer);
  112. List<ComputerEntity> computerList = mRemoteComputerManager.getComputerList();
  113. for (int i =0;i<computerList.size();i++){
  114. String str = "computerId:" + String.valueOf(computerList.get(i).computerId) +
  115. " brand:" + computerList.get(i).brand +
  116. " model:" + computerList.get(i).model ;
  117. TextView textView = new TextView(this);
  118. textView.setText(str);
  119. mShowLinear.addView(textView);
  120. }
  121. mRemoteComputerManager.registerUser(mOnComputerArrivedListener);
  122. } catch (RemoteException e) {
  123. e.printStackTrace();
  124. }
  125. break;
  126. case R.id.clear_demo3_btn:
  127. mShowLinear.removeAllViews();
  128. break;
  129. }
  130. }
  131. private void bindService(){
  132. Intent intent = new Intent();
  133. intent.setAction("com.ljd.aidl.action.COMPUTER_OBSERVER_SERVICE");
  134. mIsBindService = bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
  135. }
  136. private void unbindService(){
  137. if(!mIsBindService){
  138. return;
  139. }
  140. if (mRemoteComputerManager != null && mRemoteComputerManager.asBinder().isBinderAlive()){
  141. try {
  142. mRemoteComputerManager.unRegisterUser(mOnComputerArrivedListener);
  143. } catch (RemoteException e) {
  144. e.printStackTrace();
  145. }
  146. }
  147. unbindService(mConnection);
  148. mIsBindService = false;
  149. }
  150. }

源码下载

 

Android的IPC机制(一)——AIDL的使用的更多相关文章

  1. [置顶] 深入理解android之IPC机制与Binder框架

    [android之IPC机制与Binder框架] [Binder框架.Parcel.Proxy-Stub以及AIDL] Abstract [每个平台都会有自己一套跨进程的IPC机制,让不同进程里的两个 ...

  2. Android IPC机制之AIDL

    什么是AIDL AIDL:Android Interface Definition Language,即Android接口定义语言. Android系统中的进程之间不能共享内存,因此,需要提供一些机制 ...

  3. Android之IPC机制

    Android IPC简介 任何一个操作系统都需要有相应的IPC机制,Linux上可以通过命名通道.共享内存.信号量等来进行进程间通信.Android系统不仅可以使用了Binder机制来实现IPC,还 ...

  4. Android 进程通信机制之 AIDL

    什么是 AIDL AIDL 全称 Android Interface Definition Language,即 安卓接口描述语言.听起来很深奥,其实它的本质就是生成进程间通信接口的辅助工具.它的存在 ...

  5. android学习-IPC机制之ACtivity绑定Service通信

    bindService获得Service的binder对象对服务进行操作 Binder通信过程类似于TCP/IP服务连接过程binder四大架构Server(服务器),Client(客户端),Serv ...

  6. Android之IPC(aidl)

    IPC(Inter-Process Conmunication) 进程间通讯 在同一进程中,各个组件进行通信是十分方便的,普通的函数调用就可以解决:但是,对于处于不同进程中的组件来说,要进行通信,就需 ...

  7. Android开发艺术探索——第二章:IPC机制(上)

    Android开发艺术探索--第二章:IPC机制(上) 本章主要讲解Android的IPC机制,首先介绍Android中的多进程概念以及多进程开发模式中常见的注意事项,接着介绍Android中的序列化 ...

  8. Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用

    在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...

  9. 《Android开发艺术探索》读书笔记 (2) 第2章 IPC机制

    2.1 Android IPC简介 (1)任何一个操作系统都需要有相应的IPC机制,Linux上可以通过命名通道.共享内存.信号量等来进行进程间通信.Android系统不仅可以使用了Binder机制来 ...

随机推荐

  1. 浅谈Spark Kryo serialization

    原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3833985.html 最近在使用spark开发过程中发现当数据量很大时,如果cache数据将消耗很多的内 ...

  2. 安卓app缓存设置

    无论大型或小型应用,灵活的缓存可以说不仅大大减轻了服务器的压力,而且因为更快速的用户体验而方便了用户. Android的apk可以说是作为小型应用,其中99%的应用并不是需要实时更新的,而且诟病于蜗牛 ...

  3. 性能测试问题_Mysql数据库服务器的CPU占用很高

    MySQl服务器CPU占用很高 1.  问题描述 一个简单的接口,根据传入的号段查询号码归属地,运行性能测试脚本,20个并发mysql的CPU就很高,监控发现只有一个select语句,且表建立了索引 ...

  4. nodejs 操作mysql

    这篇文章主要介绍了nodejs中操作mysql数据库示例,本文演示了如何在NodeJS中创建创建mysql连接.mysql数据库.插入数据.查询数据等功能,需要的朋友可以参考下  引言: 继前面的No ...

  5. 2、Spring的LocalSessionFactoryBean创建过程源码分析

    spring的LocalSessionFactoryBean生成过程与hibernate的SessionFactory生成过程是高度吻合的. 为了后面源码分析,首先讲解一个接口,一个类的功能:①.接口 ...

  6. Matlab多个Figure图合成一个Fig

    案例:之前跑过的程序 已经生成了多个matlab图,现在需要进行合并到一个图中. 解决方案,利用图像句柄把figure图像中的参数读入到内存中,然后重新subplot绘制. 程序如下: clc;cle ...

  7. PHP 对象及其三大特性

    //面向过程 //类和对象 //对象:任何东西都可以成为对象,类实例化出来的东西 //类:对所有同类的对象抽象出来的东西 //info:code,name,sex,nation,birthday // ...

  8. 加密工具类 - CryptoUtils.java

    加密工具类,包含MD5,BASE64,SHA,CRC32的加密与解密方法. 源码如下:(点击下载  - CryptoUtils.java.commons-io-2.4.jar.commons-code ...

  9. 你猜……你再猜

    『男』:你喜欢我吗? 『女』:你猜. 『男』:喜欢. 『女』:你再猜. 『男』:--

  10. 可辨别iPhone真假的网址

    在如下的网址中输入iPhone的序列号,可知道该iPhone的型号,生产日期,激活状态等. 1.http://www.app111.org/ 2.http://act.weiphone.com/wet ...