AIDL与service
Posted 金洪光
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AIDL与service相关的知识,希望对你有一定的参考价值。
Service:Local service,一个进程中的多线程服务。
AIDL:remote service,不同进程间通信。
Service启动方法:
startService():调用方destroy了那么服务不会销毁,不能与调用方直接适用,不返回任何结果。
bindService():调用方destroy了那么服务也会销毁,能与调用方直接通信。返回Binder。
* bindService时可以传递Binder的形式与调用方直接通信。在调用方需override叫ServiceConnnection的类来与service直接通信。
绑定成功后通过getService()获取Service对象,将Service对象设置为null,表示绑定意外失效,Service实例不再可用。
可以参考一下log:
操作步骤先用startService启动服务,然后destroy。
然后bindService绑定服务,然后destroy的结果如下:
不难看出start方式启动服务时调用方销毁后服务不会自动stop。
而bind方式绑定服务时调用方销毁后服务自动解除绑定同时销毁。
生命周期相关:
AIDL与service的区别
你可以试一试创建两个包不用AIDL的情况。
通过ThreadRandomServiceDemo包中的ThreadRandomServiceDemo类去开启Demo中的RandomService是可以启动的但是无法获取,
有人会说利用bindService()不是利用可以ServiceConnection类返回Binder对象吗?是的,但是你无法加载Demo包(imorpt com.example.demo.RandomService)这样就我们无法与service直接数据交互通信了。
但是我们利用AIDL就可以调用其他进程(或其他project)直接通信。
AIDL是通过MyAidl.Stub.asInterface(binder);来获取binder的。
AIDL是以获取其他进程的接口来实现IPC通信的。
使用AIDL相关可以参考之前讲过的http://www.cnblogs.com/hongguang-kim/p/5165523.html
简单说明一下AIDL问价自动生成的java文件中我们可以看到Parcel。
Parcel是android系统中应用程序进程间数据传递的容器,能够在两个进程中完成数据的打包和拆包的工作,
但Parcel不同于通用意义上的序列化,Parcel的设计目的是用于高性能IPC传输,因此不能够将Parcel对象保存在任何持久存储设备上。
当数据以Parcel对象的形式传递到跨进程服务的内部时,onTransact()方法将从Parcel对象中逐一的读取每个参数,然后调用Service内部制定的方法,
并再将结果写入另一个Parcel对象,准备将这个Parcel对象返回给远程的调用者。
自定义Parcel:
首先建立AllResult.aidl文件,声明AllResult类
package edu.hrbeu.ParcelMathServiceDemo; parcelable AllResult;
在第2行代码中使用parcelable声明自定义类,这样其他的AIDL文件就可以使用这个自定义的类
构造AllResult类。AllResult类除了基本的构造函数以外,还需要有以Parcel对象为输入的构造函数,并且需要重载打包函数writeToParcel()
AllResult.java文件的完整代码如下
package edu.hrbeu.ParcelMathServiceDemo; import android.os.Parcel; import android.os.Parcelable; public class AllResult implements Parcelable { public long AddResult; public long SubResult; public long MulResult; public double DivResult; . public AllResult(long addRusult, long subResult, long mulResult, double divResult){ AddResult = addRusult; SubResult = subResult; MulResult = mulResult; DivResult = divResult; } public AllResult(Parcel parcel) { AddResult = parcel.readLong(); SubResult = parcel.readLong(); MulResult = parcel.readLong(); DivResult = parcel.readDouble(); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLong(AddResult);34. dest.writeLong(SubResult); dest.writeLong(MulResult); dest.writeDouble(DivResult); } public static final Parcelable.Creator<AllResult> CREATOR = new Parcelable.Creator<AllResult>(){ public AllResult createFromParcel(Parcel parcel){ return new AllResult(parcel); } public AllResult[] newArray(int size){ return new AllResult[size]; } }; }
AllResult类继承于Parcelable
支持通过Parcel对象实例化AllResult内容是构造函数的读取顺序。
writeToParcel()是“打包”函数,将AllResult类内部的数据,按照特定的顺序写入Parcel对象,写入的顺序必须与构造函数的读取顺序一致
静态公共字段Creator,用来使用Parcel对象构造AllResult对象。
我们可以在其他类中编写如下代码:
long addRusult = a + b; long subResult = a - b; long mulResult = a * b; double divResult = (double) a / (double)b; AllResult allResult = new AllResult(addRusult, subResult, mulResult, divResult);
我们可以通过result.AddResult变量获取其运算结果。
以上是关于AIDL与service的主要内容,如果未能解决你的问题,请参考以下文章
Binder 机制AIDL 分析 ( 创建 Service 服务 | 绑定 Service 远程服务 )