aidl parcelableWord文件下载.docx

上传人:b****2 文档编号:3277237 上传时间:2023-05-01 格式:DOCX 页数:11 大小:21.56KB
下载 相关 举报
aidl parcelableWord文件下载.docx_第1页
第1页 / 共11页
aidl parcelableWord文件下载.docx_第2页
第2页 / 共11页
aidl parcelableWord文件下载.docx_第3页
第3页 / 共11页
aidl parcelableWord文件下载.docx_第4页
第4页 / 共11页
aidl parcelableWord文件下载.docx_第5页
第5页 / 共11页
aidl parcelableWord文件下载.docx_第6页
第6页 / 共11页
aidl parcelableWord文件下载.docx_第7页
第7页 / 共11页
aidl parcelableWord文件下载.docx_第8页
第8页 / 共11页
aidl parcelableWord文件下载.docx_第9页
第9页 / 共11页
aidl parcelableWord文件下载.docx_第10页
第10页 / 共11页
aidl parcelableWord文件下载.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

aidl parcelableWord文件下载.docx

《aidl parcelableWord文件下载.docx》由会员分享,可在线阅读,更多相关《aidl parcelableWord文件下载.docx(11页珍藏版)》请在冰点文库上搜索。

aidl parcelableWord文件下载.docx

而调用(call)来自local进程或者remote进程,有什么区别呢?

尤其是以下情况(引用原文,不作翻译了,以免翻译有误):

∙Callsmadefromthelocalprocessareexecutedinthesamethreadthatismakingthecall.IfthisisyourmainUIthread,thatthreadcontinuestoexecuteintheAIDLinterface.Ifitisanotherthread,thatistheonethatexecutesyourcodeintheservice.Thus,ifonlylocalthreadsareaccessingtheservice,youcancompletelycontrolwhichthreadsareexecutinginit(butifthatisthecase,thenyoushouldn'

tbeusingAIDLatall,butshouldinsteadcreatetheinterfacebyimplementingaBinder).

∙Callsfromaremoteprocessaredispatchedfromathreadpooltheplatformmaintainsinsideofyourownprocess.Youmustbepreparedforincomingcallsfromunknownthreads,withmultiplecallshappeningatthesametime.Inotherwords,animplementationofanAIDLinterfacemustbecompletelythread-safe.

∙Theonewaykeywordmodifiesthebehaviorofremotecalls.Whenused,aremotecalldoesnotblock;

itsimplysendsthetransactiondataandimmediatelyreturns.TheimplementationoftheinterfaceeventuallyreceivesthisasaregularcallfromtheBinderthreadpoolasanormalremotecall.Ifonewayisusedwithalocalcall,thereisnoimpactandthecallisstillsynchronous.

定义AIDL接口

AIDL接口文件,和普通的接口内容没有什么特别,只是它的扩展名为.aidl。

保存在src目录下。

如果其他应用程序需要IPC,则那些应用程序的src也要带有这个文件。

AndroidSDKtools就会在gen目录自动生成一个IBinder接口文件。

service必须适当地实现这个IBinder接口。

那么客户端程序就能绑定这个service并在IPC时从IBinder调用方法。

每个aidl文件只能定义一个接口,而且只能是接口的声明和方法的声明。

1.创建.aidl文件

AIDL使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。

这些参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。

其中对于Java编程语言的基本数据类型(int,long,char,boolean等),String和CharSequence,集合接口类型List和Map,不需要import语句。

而如果需要在AIDL中使用其他AIDL接口类型,需要import,即使是在相同包结构下。

AIDL允许传递实现Parcelable接口的类,需要import.

需要特别注意的是,对于非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。

AIDL只支持接口方法,不能公开static变量。

例如(IMyService.aidl):

packagecom.demo;

importcom.demo.Person;

interfaceIMyService{

voidsavePersonInfo(inPersonperson);

List<

Person>

getAllPerson();

}

2.实现接口

创建一个类实现刚才那个aidl的接口:

publicclassRemoteServiceextendsService{

privateLinkedList<

personList=newLinkedList<

();

@Override

publicIBinderonBind(Intentintent){

returnmBinder;

}

privatefinalIMyService.StubmBinder=newIMyService.Stub(){

publicvoidsavePersonInfo(Personperson)throwsRemoteException{

if(person!

=null){

personList.add(person);

publicList<

getAllPerson()throwsRemoteException{

returnpersonList;

};

这里会看到有一个名为IMyService.Stub类,查看aidl文件生成的Java文件源代码就能发现有这么一段代码:

/**Local-sideIPCimplementationstubclass.*/

publicstaticabstractclassStubextendsandroid.os.Binderimplementscom.demo.IMyService

原来Stub类就是继承于Binder类,也就是说RemoteService类和普通的Service类没什么不同,只是所返回的IBinder对象比较特别,是一个实现了AIDL接口的Binder。

接下来就是关于所传递的数据Bean——Person类,是一个序列化的类,这里使用Parcelable接口来序列化,是Android提供的一个比Serializable效率更高的序列化类。

Parcelable需要实现三个函数:

1)voidwriteToParcel(Parceldest,intflags)将需要序列化存储的数据写入外部提供的Parcel对象dest。

而看了网上的代码例子,个人猜测,读取Parcel数据的次序要和这里的write次序一致,否则可能会读错数据。

具体情况我没试验过!

2)describeContents()没搞懂有什么用,反正直接返回0也可以

3)staticfinalParcelable.Creator对象CREATOR 

这个CREATOR命名是固定的,而它对应的接口有两个方法:

createFromParcel(Parcelsource)实现从source创建出JavaBean实例的功能

newArray(intsize)创建一个类型为T,长度为size的数组,仅一句话(returnnewT[size])即可。

估计本方法是供外部类反序列化本类数组使用。

仔细观察Person类的代码和上面所说的内容:

publicclassPersonimplementsParcelable{

privateStringname;

privateStringtelNumber;

privateintage;

publicPerson(){}

publicPerson(Parcelpl){

name=pl.readString();

telNumber=pl.readString();

age=pl.readInt();

publicStringgetName(){

returnname;

publicvoidsetName(Stringname){

this.name=name;

publicStringgetTelNumber(){

returntelNumber;

publicvoidsetTelNumber(StringtelNumber){

this.telNumber=telNumber;

publicintgetAge(){

returnage;

publicvoidsetAge(intage){

this.age=age;

publicintdescribeContents(){

return0;

publicvoidwriteToParcel(Parceldest,intflags){

dest.writeString(name);

dest.writeString(telNumber);

dest.writeInt(age);

publicstaticfinalParcelable.Creator<

CREATOR=newParcelable.Creator<

(){

publicPersoncreateFromParcel(Parcelsource){

returnnewPerson(source);

publicPerson[]newArray(intsize){

returnnewPerson[size];

然后创建Person.aidl文件,注意这里的parcelable和原来实现的Parcelable接口,开头的字母p一个小写一个大写:

parcelablePerson;

对于实现AIDL接口,官方还提醒我们:

1.调用者是不能保证在主线程执行的,所以从一调用的开始就需要考虑多线程处理,以及确保线程安全;

2.IPC调用是同步的。

如果你知道一个IPC服务需要超过几毫秒的时间才能完成地话,你应该避免在Activity的主线程中调用。

也就是IPC调用会挂起应用程序导致界面失去响应,这种情况应该考虑单独开启一个线程来处理。

3.抛出的异常是不能返回给调用者(跨进程抛异常处理是不可取的)。

3.客户端获取接口

客户端如何获取AIDL接口呢?

通过IMyService.Stub.asInterface(service)来得到IMyService对象:

privateIMyServicemRemoteService;

privateServiceConnectionmRemoteConnection=newServiceConnection(){ 

publicvoidonServiceConnected(ComponentNameclassName,IBinderservice){ 

mRemoteService=IMyService.Stub.asInterface(service);

publicvoidonServiceDisconnected(ComponentNameclassName){ 

mRemoteService=null;

在生成的IMyService.java里面会找到这样的代码:

/**

*CastanIBinderobjectintoancom.demo.IMyServiceinterface,

*generatingaproxyifneeded.

*/

publicstaticcom.demo.IMyServiceasInterface(android.os.IBinderobj){...}

而service的绑定没有什么不同:

if(mIsRemoteBound){

unbindService(mRemoteConnection);

}else{

bindService(newIntent("

com.demo.IMyService"

),

mRemoteConnection,Context.BIND_AUTO_CREATE);

mIsRemoteBound=!

mIsRemoteBound;

通过IPC调用/传递数据

客户端绑定service后就能通过IPC来调用/传递数据了,直接调用service对象的接口方法:

addPersonButton.setOnClickListener(

newView.OnClickListener(){

privateintindex=0;

publicvoidonClick(Viewview){

Personperson=newPerson();

index=index+1;

person.setName("

Person"

+index);

person.setAge(20);

person.setTelNumber("

123456"

);

try{

mRemoteService.savePersonInfo(person);

}catch(RemoteExceptione){

e.printStackTrace();

});

listPersonButton.setOnClickListener(

list=null;

list=mRemoteService.getAllPerson();

if(list!

StringBuildertext=newStringBuilder();

for(Personperson:

list){

text.append("

\nPersonname:

"

text.append(person.getName());

\n 

age:

text.append(person.getAge());

\ntelnumber:

text.append(person.getTelNumber());

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2