Android AIDL 使用
一、概述:
aidl是android中ipc(inter-process communication)方式中的一种,aidl是android interface definition language的缩写。
其主要作用是用于进程间额通讯。
- 八种基本数据类型:byte、char、short、int、long、float、double、boolean
- string,charsequence
- 实现了parcelable接口的数据类型
- list 类型。list承载的数据必须是aidl支持的类型,或者是其它声明的aidl对象
- map类型。map承载的数据必须是aidl支持的类型,或者是其它声明的aidl对象
2、
aidl文件可以分为两类。一类用来声明实现了parcelable接口的数据类型,以供其他aidl文件使用那些非默认支持的数据类型。还有一类是用来定义接口方法,声明要暴露哪些接口给客户端调用,定向tag就是用来标注这些方法的参数值。
3、
明确导包。在aidl文件中需要明确标明引用到的数据类型所在的包名,即使两个文件处在同个包名下。
三、编写代码:
创建两个工程,一个作为服务端,一个作为客户端,客户端绑定服务端service,然后调用方法向服务端获取书籍列表,向服务端添加书籍。
1、服务端:
(1)、创建aidl文件book.aidl
创建后便可以在目录里看到aidl文件。
接下来定义book类,注意books类的包名必须与book.aidl包名一样,但是不可与book.aidl在同一个目录下。
book.class的代码如下,其必须继承parcelable接口:
package com.status.aidlproject.com.aidl; import android.os.parcel; import android.os.parcelable; public class book implements parcelable { private string bookname; public book(string name) { bookname = name; } public string getbookname() { return bookname; } public void setbookname(string bookname) { this.bookname = bookname; } protected book(parcel in) { bookname = in.readstring(); } public static final creator<book> creator = new creator<book>() { @override public book createfromparcel(parcel in) { return new book(in); } @override public book[] newarray(int size) { return new book[size]; } }; @override public int describecontents() { return 0; } @override public void writetoparcel(parcel dest, int flags) { dest.writestring(bookname); } public void readfromparcel(parcel desc) { bookname = desc.readstring(); } @override public string tostring() { return "bookname=" + bookname; } }
接下来修改book.aidl文件,将其声明为parcelable类型,并且需要注意的是,原先默认的interface接口需要去掉,否则编译会报错。
// book.aidl package com.status.aidlproject.com.aidl; // declare any non-default types here with import statements parcelable book; //需要删除 /*interface book { void default(string s); }*/
接下来便是要定义服务端暴露给客户端的接口了(获取书籍列表,添加书籍)
在同样的目录定义aidl文件bookmanager.aidl
代码如下:
// bookmanager.aidl package com.status.aidlproject.com.aidl; // declare any non-default types here with import statements import com.status.aidlproject.com.aidl.book; interface bookmanager { list<book> getbooklist(); void addbook(inout book book); }
注意要把包手动导进来。
接下来,make project便可以看到aidl编译成代码文件
这个文件才是我们真正需要用到的。
(2)、创建service,供客户端绑定
package com.status.aidlproject; import android.app.service; import android.content.intent; import android.content.serviceconnection; import android.os.ibinder; import android.support.annotation.nullable; import android.util.log; import com.status.aidlproject.com.aidl.book; import com.status.aidlproject.com.aidl.bookmanager; import java.util.arraylist; import java.util.list; public class bookservice extends service { private final string tag = bookservice.class.getsimplename(); private list<book> list; @override public void oncreate() { super.oncreate(); list = new arraylist<>(); for (int i = 0; i < 5; i++) { book book = new book("第" + i + "本书"); list.add(book); } } @nullable @override public ibinder onbind(intent intent) { return bookmanager; } private bookmanager.stub bookmanager = new bookmanager.stub() { @override public list<book> getbooklist() { log.d(tag, "getbooklist"); return list; } @override public void addbook(book book) { log.d(tag, "addbook"); if (book != null) { list.add(book); } log.d(tag, book.tostring()); } }; @override public void unbindservice(serviceconnection conn) { super.unbindservice(conn); } @override public void ondestroy() { super.ondestroy(); } }
manifests文件中可以这样写:
<service android:name=".bookservice" android:enabled="true" android:exported="true" android:process=":remote"> <intent-filter> <action android:name="android.intent.action.bookservice" /> </intent-filter> </service>
onbind方法返回的是bookmanager.stub对象,实现里面的两个方法,客户端拿到这个对象后就可以与服务端通讯了。
2、客户端
(1)
将aidl文件与book.class拷贝到客户端的工程,注意他们的目录需要与服务端的一样,也就是说aidl与book.class包名要与服务端的一样。
make project一下便会生成编译后的文件
(2)、编写代码,与服务端连接:
package com.status.aidlclient; import android.content.componentname; import android.content.context; import android.content.intent; import android.content.serviceconnection; import android.os.ibinder; import android.os.remoteexception; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.util.log; import android.view.view; import android.widget.textview; import com.status.aidlproject.com.aidl.book; import com.status.aidlproject.com.aidl.bookmanager; import com.status.aidlproject.com.aidl.imyconnect; import java.util.list; public class mainactivity extends appcompatactivity { private final string tag = mainactivity.class.getsimplename();private textview textview3; private textview textview4; private textview textview5; private final string action1 = "android.intent.action.connectservice"; private final string action2 = "android.intent.action.bookservice"; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); textview3 = findviewbyid(r.id.text3); textview4 = findviewbyid(r.id.text4); textview5 = findviewbyid(r.id.text5); textview3.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { intent intent = new intent(action2); // 注意在 android 5.0以后,不能通过隐式 intent 启动 service,必须制定包名 intent.setpackage("com.status.aidlproject"); bindservice(intent, connection2, context.bind_auto_create); } }); textview4.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { try { if (manager != null) { list<book> list = manager.getbooklist(); log.d(tag, "getbooklist:" + list); } } catch (remoteexception e) { e.printstacktrace(); } } }); textview5.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { book book = new book("添加的书"); try { if (manager != null) { manager.addbook(book); } } catch (remoteexception e) { e.printstacktrace(); } } }); } private bookmanager manager; serviceconnection connection2 = new serviceconnection() { @override public void onserviceconnected(componentname name, ibinder service) { log.d(tag, "onserviceconnected"); manager = bookmanager.stub.asinterface(service); } @override public void onservicedisconnected(componentname name) { manager = null; } }; }
textview3用于绑定服务端
textview4用于获取服务端书籍列表
textview5用于向服务端添加书籍
转载请标明出处:https://www.cnblogs.com/tangzh/p/10775848.html
参考: