Android Studio创建AIDL文件并实现进程间通讯实例
在android系统中,跨进程通信是非常普遍的事情,它用到了binder机制处理进程之间的交互。binder机制会开放一些接口给java层,供android开发工程师调用进程之间通信。这些接口android封装到了aidl文件里,当我们项目用到跨进程通信时可以创建.aidl文件,.aidl文件可以协助我们达到跨进程的通信。下面简单介绍用androidstudio创建aidl文件的过程。
a.新建aidl文件
1.项目文件夹右键---> new --->选择aidl
2.自定义一个接口名称
3.创建之后我们看到了xxx.aidl文件,然后编辑自己项目需要实现的方法,这里很简单就获取一个字符串的方法getallname。
4.写好之后,我们需要重新rebuild,完后在项目build/generated/source/aidl/debug/包名 目录下就看到了系统为我们生成的以刚才.aidl文件名命名的java文件。
该java文件系统会自动生成代码:
stub:描述了一个java服务,对应是一个远程的service。
proxy:描述了一个java服务的代理对象,在client端就会得到这个对象。
这两者都实现了ipersonmanager接口。
asinterface:将java服务的代理对象即一个binderproxy封装成了一个ipersonmanager.stub.proxy对象,实现了ipersonmanager接口。
ontransact:负责接收分发进程间的通信。它首先会收到client发来的请求,不同的方法进入相应的case代码中,然后交给stub的子类去处理事件,例如 java.lang.string _result = this.getallname(); 这里的this就可以让它的子类去接收该请求并处理。
ibinder的transact方法:用来发送进程间的请求。
b.利用aidl实现进程间的通讯
一:接口文件中只含有基础数据类型
如上aidl文件,ipersonmanager中只用到了基本数据类型,此时要完善server端的小项目,还需要新建一个service。
server端代码如下
public class personservice extends service { private static string names = "alice & iland"; public personbinder mpersonbinder; @override public void oncreate() { super.oncreate(); mpersonbinder = new personbinder(); } @override public ibinder onbind(intent intent) { return mpersonbinder; } public class personbinder extends ipersonmanager.stub{ @override public string getallname() throws remoteexception { return names; } } }
继承系统的service,并建立一个内部类继承ipersonmanager.stub,这里很简单,当客户端请求要获取名字时我们这里把names给到客户端。
client端代码如下
public class mainactivity extends appcompatactivity implements view.onclicklistener{ private static final string tag = "mainactivity"; private button btnget; private edittext etshow; public ipersonmanager mipersonmanager; serviceconnection sc = new serviceconnection() { @override public void onserviceconnected(componentname name, ibinder service) { log.i(tag, "onserviceconnected: "); mipersonmanager = ipersonmanager.stub.asinterface(service); } @override public void onservicedisconnected(componentname name) { log.i(tag, "onservicedisconnected: "); mipersonmanager = null; } }; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); btnget = (button) findviewbyid(r.id.btn_getname); etshow = (edittext) findviewbyid(r.id.et_allnamef); btnget.setonclicklistener(this); intent intent = new intent("com.ly.testaidlserver.aidl.aidl_service"); intent.setpackage("com.ly.testaidlserver"); bindservice(intent,sc, service.bind_auto_create); } @override public void onclick(view v) { switch (v.getid()){ case r.id.btn_getname: string names = null; try { if (mipersonmanager!=null) names = mipersonmanager.getallname(); } catch (remoteexception e) { e.printstacktrace(); } etshow.settext(names); break; default: break; } }@override protected void ondestroy() { super.ondestroy(); unbindservice(sc); } }
在onserviceconnected方法中拿到ipersonmanager的代理对象,最终获取到 alice & ilan,与服务端数据一致。
注意:
1.bindservice方法在5.0以后做出改变,隐式意图需要设置package 或者 commponent,直接定义一个action是报异常的。
intent intent = new intent("com.ly.testaidlserver.aidl.aidl_service"); intent.setpackage("com.ly.testaidlserver"); bindservice(intent,sc, service.bind_auto_create);
2.我们需要把server端的aidl文件复制到client端,在client中存放aidl的文件夹也需要跟server端包名一致。
如图:
上图为aidl文件在server端存放的路径,下图为复制到client端aidl文件的路径,这里要保持一致,因此client端需要针对server端的包名新建一个package。
3.当我们启动项目的时候,如果在activity中ipersonmanager找不到报出异常,请在app的build.gradle中添加aidl文件指名目录,如本例中添加,
sourcesets{ main { aidl.srcdirs = ['src/main/aidl','src/main/java'] } }
二:接口文件中含有复杂数据类型、
1.新建一个person.aidl 内容非常简单
parcelable person;
2.新建一个person实体类,为了能在进程间进行通信必须实现parcelable接口。
3.在ipersonmanager中添加了一个方法,这里注意用到的person类必须将包名improt进去。
4.将ipersonmanager.aidl、person.aidl、person.java复制到客户端的aidl包下。
5.查看是否需要修改build.gradle中sourcesets设置
代码基本没有变化:
person.java
public class person implements parcelable { string name; int age; public person(string name, int age) { this.name = name; this.age = age; } public static final creator<person> creator = new creator<person>() { @override public person createfromparcel(parcel in) { return new person(in.readstring(), in.readint()); } @override public person[] newarray(int size) { return new person[size]; } }; @override public int describecontents() { return 0; } @override public void writetoparcel(parcel dest, int flags) { dest.writestring(name); dest.writeint(age); } public string getname() { return name; } public void setname(string name) { this.name = name; } public int getage() { return age; } public void setage(int age) { this.age = age; } }
ipersonmanager.aidl
interface ipersonmanager { string getallname(); list<person> getpersonlist(); }
server
public class personservice extends service { private list<person> persons = new arraylist<person>(); public personbinder mpersonbinder; @override public void oncreate() { super.oncreate(); mpersonbinder = new personbinder(); person p1 = new person("alice",23); persons.add(p1); person p2 = new person("iland",18); persons.add(p2); } @override public ibinder onbind(intent intent) { return mpersonbinder; } public class personbinder extends ipersonmanager.stub{ @override public string getallname() throws remoteexception { return ""; } @override public list<person> getpersonlist() throws remoteexception { return persons; } } }
clent
public class mainactivity extends appcompatactivity implements view.onclicklistener{ private static final string tag = "mainactivity"; private button btnget; private edittext etshow; public ipersonmanager mipersonmanager; serviceconnection sc = new serviceconnection() { @override public void onserviceconnected(componentname name, ibinder service) { log.i(tag, "onserviceconnected: "); mipersonmanager = ipersonmanager.stub.asinterface(service); } @override public void onservicedisconnected(componentname name) { log.i(tag, "onservicedisconnected: "); mipersonmanager = null; } }; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); btnget = (button) findviewbyid(r.id.btn_getname); etshow = (edittext) findviewbyid(r.id.et_allnamef); btnget.setonclicklistener(this); intent intent = new intent("com.ly.testaidlserver.aidl.aidl_service"); intent.setpackage("com.ly.testaidlserver"); bindservice(intent,sc, service.bind_auto_create); } @override public void onclick(view v) { switch (v.getid()){ case r.id.btn_getname: arraylist<person> persons = null; try { if (mipersonmanager!=null) persons = (arraylist<person>) mipersonmanager.getpersonlist(); } catch (remoteexception e) { e.printstacktrace(); } string result = ""; for (person person : persons){ result = result+person.getname()+"__"+person.getage(); } etshow.settext(result); break; default: break; } }@override protected void ondestroy() { super.ondestroy(); unbindservice(sc); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 自制雪糕健康诱人,你还不会做?