小猪的Android入门之路 Day 9 part 2

小猪的Android入门之路 Day 9 part 2

Android四大组件之——AIDL实现跨进程通信

                                                 ——转账请注明出处:coder-pig

本节引言:

在上一part中我们对Service进行了简单的学习:

什么是Service,Service的生命周期,StartService和BindService的区别以及使用

IntentService来解决Service的异步问题;

而在今天的这一Part中将会研究另一个东西:IPC,安卓给我们提供了AIDL Service

来完成进程间的数据交换!好了,开始本节的内容吧!


本节学习路线图:



正文:


看这篇博文的人,不知道你能不能坚持地看完本篇内容,为了照顾你们,直接把总结用法放到本文的开头!







AIDL简介:


开头我们说的IPC,全名叫做跨进程通信(interprocess communication),因为在Android系统中,

个个应用程序都运行在自己的进程中,进程之间一般是无法直接进行数据交换的,而为了实现跨进程

间的通信,Android给我们提供了AIDL技术,AIDL(Android Interface Definition Language)是一种

接口语言,语法十分的简单,这种接口语言并不是真正的编程语言,只是定义两个进程间的通信接口而已!

而生成符合通信协议的Java代码则是由Android SDKplatform-tools下的aidl.exe工具自动地在gen

目录下生成一个对应的Xxx.java的接口,在该接口中包含一个Stub的内部类,在该类中实现了IBinder接口

与自定义的通信接口,这个类将会作为远程Service的回调类——实现了IBinder接口,所以可作为Service

的onBind( )方法的返回值



使用AIDL完成两个进程之间的简单通信

一.建立作为服务端的工程:

step 1:创建IPerson.aidl文件,不要直接new file然后建立哦!这样的话是打不开文件,从而不能编写代码哦!

①直接新建一个txt文件,编写好后保存为.aidl格式,然后复制到对应路径下

②因为aidl和接口类似,所以直接new interface,编写好内容后,来到对应java文件所在目录下修改文件后缀名;

然后点击刷新即可,另外编写ADIL文件时有以下注意事项:

1.接口名词需要与aidl文件名相同

2.接口和方法前面不要加访问权限修饰符:public ,private,protected等,也不能用static final!

3.AIDL默认支持的类型包括Java基本类型,String,List,Map,CharSequence,除此之外的其他类型都需要import

声明,对于使用自定义类型作为参数或者返回值,自定义类型需要实现Parcelable接口,详情请看后面的传递复杂数据类型

4.自定义类型和AIDL生成的其它接口类型在aidl描述文件中,应该显式import,即便在该类和定义的包在同一个包中。


编写IPerson.aidl文件内容如下:

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.example.aidl;  
  2.   
  3. interface IPerson {  
  4.     String queryPerson(int num);  
  5. }  
此时只要我们按下刷新或者不用,就可以看到gen目录下生成了一个接口对应的实现:

我们可以打开IPerson.java看看里面的代码

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

我们关注的只是asInterface(IBinder)和我们定义的接口中的queryPerson()方法!

该方法会把IBinder类型的对象转换成IPerson类型的,必要时生成一个代理对象返回结果!

当然,你也可以选择不看,因为我们完全可以跳过这里去进行下一步,这里只是了解下而已!



step 2:自定义我们的Service类,完成下述操作:

1)继承Service类,同时也自定义了一个PersonQueryBinder类用来继承IPerson.Stub类

就是实现了IPerson接口和IBinder接口

2)实例化自定义的Stub类,并重写Service的onBind方法,返回一个binder对象!

AidlService.java

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.example.aidl_service;  
  2.   
  3. import com.example.aidl.IPerson.Stub;  
  4.   
  5. import android.app.Service;  
  6. import android.content.Intent;  
  7. import android.os.IBinder;  
  8. import android.os.RemoteException;  
  9.   
  10. public class AidlService extends Service {  
  11.   
  12.     private IBinder binder = new PersonQueryBinder();  
  13.     private String[] names = {"小涛","刘老师","蓝翔","挖掘机"};  
  14.               
  15.     @Override  
  16.     public IBinder onBind(Intent intent) {        
  17.         return binder;  
  18.     }  
  19.   
  20.     private String query(int num)  
  21.     {  
  22.         if(num > 0 && num < 5){  
  23.             return names[num - 1];  
  24.         }  
  25.         return null;  
  26.     }  
  27.       
  28.       
  29.     private final class PersonQueryBinder extends Stub{  
  30.         @Override  
  31.         public String queryPerson(int num) throws RemoteException {  
  32.             return query(num);  
  33.         }  
  34.     }  
  35.       
  36. }  


step 3:在AndroidManifest.xml文件中注册Service

[html]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1.   <service android:name=".AidlService">  
  2.       <intent-filter>    
  3.         <action android:name="android.intent.action.AIDLService" />  
  4.     <category android:name="android.intent.category.DEFAULT" />  
  5. </intent-filter>    
  6.   </service>  

这里并没有提供Activity界面,当着没关系,该应用提供的Service可以供其他app来调用!


二.建立作为客户端的工程:

首先需要把我们把服务端创建的IPerson.aidl文件复制过来,然后

我们直接在MainActvivity中完成,和绑定本地Service的操作类似:

1)自定义PersonConnection类实现ServiceConnection接口

2)以PersonConnection对象作为参数,调用bindService绑定远程Service

bindService(service, conn, BIND_AUTO_CREATE);

ps:第三个参数是设置如果服务没有启动的话,自动创建

3)和本地Service不同,绑定远程Service的ServiceConnection不能直接获取Service的onBind( )方法

返回的IBinder对象,只能返回onBind( )方法所返回的代理对象,需要做如下处理:

iPerson = IPerson.Stub.asInterface(service);

再接着完成初始化,以及按钮事件等就可以了


MainActvitiy.java

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.jay.example.aidl_client;  
  2.   
  3. import com.example.aidl.IPerson;  
  4.   
  5. import android.app.Activity;  
  6. import android.content.ComponentName;  
  7. import android.content.Intent;  
  8. import android.content.ServiceConnection;  
  9. import android.os.Bundle;  
  10. import android.os.IBinder;  
  11. import android.os.RemoteException;  
  12. import android.view.View;  
  13. import android.view.View.OnClickListener;  
  14. import android.widget.Button;  
  15. import android.widget.EditText;  
  16. import android.widget.TextView;  
  17.   
  18.   
  19. public class MainActivity extends Activity {  
  20.   
  21.     private EditText editnum;  
  22.     private Button btnquery;  
  23.     private TextView txtshow;  
  24.     private IPerson iPerson;  
  25.     private PersonConnection conn = new PersonConnection();  
  26.       
  27.     @Override  
  28.     protected void onCreate(Bundle savedInstanceState) {  
  29.         super.onCreate(savedInstanceState);  
  30.         setContentView(R.layout.activity_main);  
  31.           
  32.         editnum = (EditText) findViewById(R.id.editnum);  
  33.         btnquery = (Button) findViewById(R.id.btnquery);  
  34.         txtshow = (TextView) findViewById(R.id.txtshow);  
  35.           
  36.         Intent service = new Intent("android.intent.action.AIDLService");  
  37.         bindService(service, conn, BIND_AUTO_CREATE);  
  38.           
  39.         btnquery.setOnClickListener(new OnClickListener() {  
  40.               
  41.             @Override  
  42.             public void onClick(View v) {  
  43.                 String number = editnum.getText().toString();  
  44.                 int num = Integer.valueOf(number);  
  45.                 try {  
  46.                     txtshow.setText(iPerson.queryPerson(num));  
  47.                 } catch (RemoteException e) {  
  48.                     e.printStackTrace();  
  49.                 }  
  50.             }  
  51.         });  
  52.           
  53.     }  
  54.       
  55.       
  56.       
  57.   
  58.     @Override  
  59.     protected void onDestroy() {  
  60.         unbindService(conn);  
  61.         super.onDestroy();  
  62.     }  
  63.       
  64.       
  65.       
  66.     private final class PersonConnection implements ServiceConnection {  
  67.         public void onServiceConnected(ComponentName name, IBinder service) {  
  68.             iPerson = IPerson.Stub.asInterface(service);  
  69.         }  
  70.         public void onServiceDisconnected(ComponentName name) {  
  71.             iPerson = null;  
  72.         }  
  73.     }  
  74.   
  75. }  


然后先启动我们的AIDL_Service,再接着启动AIDL_Cilent,输入要查询的姓名序号,即可知道对应姓名!

当然也可以直接启动AIDL_Client,也可以获得相同的结果!

效果图:


好了,对于AIDLService的简单实用示例就到这里,后续如果有更好的例子会再给出!



传递复杂数据的AIDL Service


上面的简单示例中,客户端向服务端发送了一个int类型的参数,然后服务端返回一个String类型的参数,看似已经

基本满足我们的需求了,但是实际情况下,我们还需要考虑向客户端传递复杂数据类型的情况!那么下面就来讲

解下如何向服务端传递复杂数据类型的问题!


1.先要了解的是Parcelable接口,对于自定义类型,Android规定调用远程Service的参数与返回值都必须实现

Parcelable接口,该接口告诉Android运行时在封送(marshalling)解封送(unmarshalling)过程中如何序列化

与反序列化对象,这个时候你或许会有疑惑,为什么不直接用Java提供的Serializable接口呢?这是因为Android

团队觉得Java序列化太慢,难以满足Android的进程间的通信需求,所以他们构建了Parcelable方案!

---->也就是自定义的对象要实现Parcelable接口!实现接口要实现下述方法

实现Paecelable接口意味着要实现writeToParcelreadFromPacel方法;

写入方法将对象写入到包裹(parcel)中,而读取方法则从包裹中读取对象,请注意,写入属性顺序需与读取顺序相同

需要在该类中添加一个名为CREATOR的static final属性,该属性需要实现android.os.Parcelable.Creator<T>接口

里面的两个方法

createFromParcel(Parcel source)方法:实现从source创建出JavaBean实例的功能

newArray(int size):创建一个类型为T,长度为size的数组,只有一个简单的return new T[size]; (这里的T是Person类)

※describeContents():这个我也不知道是拿来干嘛的,直接返回0即可!不用理他



2.非原始类型中,除了String和CharSequence以外,其余均需要一个方向指示符。方向指示符包括

in、out、和inout。in表示由客户端设置,out表示由服务端设置,inout表示客户端和服务端都设置了该值。



代码实例:

这里我们自定义两种对象类型:Person与Salary,Person作为调用远程的Service的参数,Salary作为返回值!

那么首先要做的就是创建Person与Salary类,同时需要实现Parcelable接口 


一.服务端的编写


step 1.先建立Person.aidl和Salary.aidl的文件,因为这两个需要实现Parcelable接口,就下面简单的一句!

Person.aidl:     parcelable Person; 
Salary.aidl:     parcelable Salary;  


step 2.分别建立Person类与Salary类,都需要实现Parcelable接口.重写对应的方法!

另外因为我们后面是根据Person对象来获取Map集合中的数据,所以Person.java中我们重写了hashcode和equals

的方法;而Salary类则不需要!

Person.java:

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.jay.example.aidl;  
  2.   
  3. import android.os.Parcel;  
  4. import android.os.Parcelable;  
  5.   
  6. public class Person implements Parcelable{  
  7.     private Integer id;  
  8.     private String name;  
  9.       
  10.     public Person(){}  
  11.       
  12.     public Person(Integer id, String name) {  
  13.         super();  
  14.         this.id = id;  
  15.         this.name = name;  
  16.     }  
  17.   
  18.   
  19.     public Integer getId() {  
  20.         return id;  
  21.     }  
  22.   
  23.     public void setId(Integer id) {  
  24.         this.id = id;  
  25.     }  
  26.   
  27.     public String getName() {  
  28.         return name;  
  29.     }  
  30.   
  31.     public void setName(String name) {  
  32.         this.name = name;  
  33.     }  
  34.   
  35.     //实现Parcelable必须实现的方法,不知道拿来干嘛的,直接返回0就行了  
  36.     @Override  
  37.     public int describeContents() {  
  38.         return 0;  
  39.     }  
  40.   
  41.     //写入数据到Parcel中的方法  
  42.     @Override  
  43.     public void writeToParcel(Parcel dest, int flags) {  
  44.         //把对象所包含的数据写入到parcel中  
  45.         dest.writeInt(id);  
  46.         dest.writeString(name);       
  47.     }  
  48.       
  49.     //必须提供一个名为CREATOR的static final属性 该属性需要实现  
  50.     //android.os.Parcelable.Creator<T>接口   
  51.      public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {  
  52.   
  53.         //从Parcel中读取数据,返回Person对象   
  54.         @Override  
  55.         public Person createFromParcel(Parcel source) {  
  56.             return new Person(source.readInt(),source.readString());  
  57.         }  
  58.   
  59.         @Override  
  60.         public Person[] newArray(int size) {  
  61.             return new Person[size];  
  62.         }  
  63.       
  64.        
  65.      };  
  66.       
  67.     //因为我们集合取出元素的时候是根据Person对象来取得,所以比较麻烦,  
  68.     //需要我们重写hashCode()和equals()方法  
  69.         @Override  
  70.         public int hashCode()  
  71.         {  
  72.             final int prime = 31;  
  73.             int result = 1;  
  74.             result = prime * result + ((name == null) ? 0 : name.hashCode());  
  75.             return result;  
  76.         }  
  77.         @Override  
  78.         public boolean equals(Object obj)  
  79.         {  
  80.             if (this == obj)  
  81.                 return true;  
  82.             if (obj == null)  
  83.                 return false;  
  84.             if (getClass() != obj.getClass())  
  85.                 return false;  
  86.             Person other = (Person) obj;  
  87.             if (name == null)  
  88.             {  
  89.                 if (other.name != null)  
  90.                     return false;  
  91.             }  
  92.             else if (!name.equals(other.name))  
  93.                 return false;  
  94.             return true;  
  95.         }  
  96.        
  97.        
  98. }  

接着是Salary类了,照葫芦画瓢,都是类似的:

Salary.java:

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.jay.example.aidl;  
  2.   
  3. import android.os.Parcel;  
  4. import android.os.Parcelable;  
  5.   
  6. public class Salary implements Parcelable{  
  7.     private String type;  
  8.     private Integer salary;  
  9.       
  10.     public Salary(){}  
  11.       
  12.   
  13.     public Salary(String type, Integer salary) {  
  14.         super();  
  15.         this.type = type;  
  16.         this.salary = salary;  
  17.     }  
  18.   
  19.     public String getType() {  
  20.         return type;  
  21.     }  
  22.   
  23.   
  24.     public void setType(String type) {  
  25.         this.type = type;  
  26.     }  
  27.   
  28.   
  29.     public Integer getSalary() {  
  30.         return salary;  
  31.     }  
  32.   
  33.   
  34.     public void setSalary(Integer salary) {  
  35.         this.salary = salary;  
  36.     }  
  37.   
  38.   
  39.     //实现Parcelable必须实现的方法,不知道拿来干嘛的,直接返回0就行了  
  40.     @Override  
  41.     public int describeContents() {  
  42.         return 0;  
  43.     }  
  44.   
  45.     //写入数据到Parcel中的方法  
  46.     @Override  
  47.     public void writeToParcel(Parcel dest, int flags) {  
  48.         //把对象所包含的数据写入到parcel中  
  49.         dest.writeString(type);  
  50.         dest.writeInt(salary);  
  51.     }  
  52.       
  53.     //必须提供一个名为CREATOR的static final属性 该属性需要实现  
  54.     //android.os.Parcelable.Creator<T>接口   
  55.      public static final Parcelable.Creator<Salary> CREATOR = new Parcelable.Creator<Salary>() {  
  56.   
  57.         //从Parcel中读取数据,返回Person对象   
  58.         @Override  
  59.         public Salary createFromParcel(Parcel source) {  
  60.             return new Salary(source.readString(),source.readInt());  
  61.         }  
  62.   
  63.         @Override  
  64.         public Salary[] newArray(int size) {  
  65.             return new Salary[size];  
  66.         }  
  67.       
  68.        
  69.      };  
  70.       
  71.     public String toString()   
  72.     {  
  73.         return "工作:"+type+"    薪水"+salary;  
  74.     };  
  75.       
  76. }  


嗯呢,完成上述四个文件后,接着就搞个ISalary.aidl了,我们在里面只写一个简单的获取工资信息的方法

ISalary.aidl:

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.jay.example.aidl;  
  2.   
  3. import com.jay.example.aidl.Salary;  
  4. import com.jay.example.aidl.Person;  
  5. interface ISalary  
  6. {  
  7.     //定义一个Person对象作为传入参数  
  8.     //接口中定义方法时,需要制定新参的传递模式,这里是传入,所以前面有一个in  
  9.     Salary getMsg(in Person owner);  
  10. }        

ps:这里可以记得如果使用的是自定义的数据类型的话,需要import哦!!!切记!!!

接着就到服务端的核心Service的编写了!

定义一个SalaryBinder类继承Stub,从而实现ISalary和IBinder接口;定义一个存储信息的Map集合!

重新onBind方法,返回SalaryBinder类的对象实例!

AidlService.java

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.jay.example.aidl_complexservice;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. import com.jay.example.aidl.ISalary.Stub;  
  7. import com.jay.example.aidl.Person;  
  8. import com.jay.example.aidl.Salary;  
  9.   
  10. import android.app.Service;  
  11. import android.content.Intent;  
  12. import android.os.IBinder;  
  13. import android.os.RemoteException;  
  14.   
  15. public class AidlService extends Service {  
  16.   
  17.     private SalaryBinder salaryBinder;  
  18.     private static Map<Person,Salary> ss = new HashMap<Person, Salary>();  
  19.     //初始化Map集合,这里在静态代码块中进行初始化,当然你可也以在构造方法中完成初始化  
  20.     static  
  21.     {  
  22.         ss.put(new Person(1"Jay"), new Salary("码农"2000));  
  23.         ss.put(new Person(2"GEM"), new Salary("歌手"20000));  
  24.         ss.put(new Person(3"XM"), new Salary("学生"20));  
  25.         ss.put(new Person(4"MrWang"), new Salary("老师"2000));  
  26.     }  
  27.       
  28.       
  29.     @Override  
  30.     public void onCreate() {  
  31.         super.onCreate();  
  32.         salaryBinder = new SalaryBinder();  
  33.     }  
  34.       
  35.     @Override  
  36.     public IBinder onBind(Intent intent) {  
  37.         return salaryBinder;  
  38.     }  
  39.   
  40.       
  41.     //同样是继承Stub,即同时实现ISalary接口和IBinder接口  
  42.     public class SalaryBinder extends Stub  
  43.     {  
  44.   
  45.         @Override  
  46.         public Salary getMsg(Person owner) throws RemoteException {  
  47.             return ss.get(owner);  
  48.         }  
  49.           
  50.     }  
  51.       
  52.     @Override  
  53.     public void onDestroy() {  
  54.         System.out.println("服务结束!");  
  55.         super.onDestroy();  
  56.     }  
  57.       
  58.       
  59.       
  60.       
  61.       
  62. }  

最后别忘了需要在AndroidManifest.xml文件中注册Service哦!

[html]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. <service android:name=".AidlService">  
  2.            <intent-filter>    
  3.             <action android:name="android.intent.action.AIDLService" />  
  4.             <category android:name="android.intent.category.DEFAULT" />  
  5.         </intent-filter>    
  6.        </service>  






二.客户端的编写:

1.先把服务端的AIDL的文件直接拷贝过来,拷贝后的目录如下:


2.编写简单的布局,再接着就是核心MainActvitiy的实现了

定义一个ServciceConnection对象,重写对应方法,和前面的普通数据的类似

再接着在bindService,然后再Button的点击事件中获取Salary对象并显示出来!

MainActivity.java

[java]   view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. package com.jay.example.aidl_complexclient;  
  2.   
  3. import com.jay.example.aidl.ISalary;  
  4. import com.jay.example.aidl.Person;  
  5. import com.jay.example.aidl.Salary;  
  6.   
  7. import android.app.Activity;  
  8. import android.app.Service;  
  9. import android.content.ComponentName;  
  10. import android.content.Intent;  
  11. import android.content.ServiceConnection;  
  12. import android.os.Bundle;  
  13. import android.os.IBinder;  
  14. import android.os.RemoteException;  
  15. import android.view.View;  
  16. import android.view.View.OnClickListener;  
  17. import android.widget.Button;  
  18. import android.widget.EditText;  
  19. import android.widget.TextView;  
  20.   
  21.   
  22. public class MainActivity extends Activity {  
  23.   
  24.     private ISalary salaryService;  
  25.     private Button btnquery;  
  26.     private EditText editname;  
  27.     private TextView textshow;  
  28.     private ServiceConnection conn = new ServiceConnection() {  
  29.           
  30.         @Override  
  31.         public void onServiceDisconnected(ComponentName name) {  
  32.             salaryService = null;  
  33.         }  
  34.           
  35.         @Override  
  36.         public void onServiceConnected(ComponentName name, IBinder service) {  
  37.             //返回的是代理对象,要调用这个方法哦!  
  38.             salaryService = ISalary.Stub.asInterface(service);  
  39.         }  
  40.     };  
  41.       
  42.       
  43.     @Override  
  44.     protected void onCreate(Bundle savedInstanceState) {  
  45.         super.onCreate(savedInstanceState);  
  46.         setContentView(R.layout.activity_main);  
  47.           
  48.         btnquery = (Button) findViewById(R.id.btnquery);  
  49.         editname = (EditText) findViewById(R.id.editname);  
  50.         textshow = (TextView) findViewById(R.id.textshow);  
  51.           
  52.         Intent it = new Intent();  
  53.         it.setAction("com.jay.aidl.AIDL_SERVICE");  
  54.         bindService(it, conn, Service.BIND_AUTO_CREATE);  
  55.           
  56.         btnquery.setOnClickListener(new OnClickListener() {           
  57.             @Override  
  58.             public void onClick(View v) {  
  59.                 try  
  60.                 {  
  61.                     String name = editname.getText().toString();  
  62.                     Salary salary = salaryService.getMsg(new Person(1,name));  
  63.                     textshow.setText(name + salary.toString());  
  64.                 }catch(RemoteException e){e.printStackTrace();}  
  65.             }  
  66.         });  
  67.           
  68.     }  
  69.     @Override  
  70.     protected void onDestroy() {  
  71.         super.onDestroy();  
  72.         this.unbindService(conn);  
  73.     }  
  74.       
  75. }  


运行截图:



好了,关于Android中的跨进程IPC的代表AIDL就讲解到这里,如果后续有什么新的知识点会

在进行补偿!谢谢支持!大笑




本节相关代码下载:

1)使用AIDL完成进程间的简单通信:点击下载

2)传递复杂数据的AIDL Service的实现:点击下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值