今天我总结一下AIDL文件中含有对象的调用。本人比较笨,用词方面可能不是很准确。要实现AIDL文件中含有对象的调用,要用到Android中的Parcelable这个接口。
下面通过一个具体的实例看看到底如何实现AIDL文件中含有对象的调用。
1. 建立AIDL文件
同样还是建立一个AIDL文件,如下:
package com.android.zinc;
import com.android.zinc.MathFunction;
interface IMyService{
float calculateResult(in MathFunction myMathFunction);
}
这个AIDL文件,仅有一个方法calculateResult,返回一个float类型的结果,但是这个方法中有一个MathFunction的对象,像这样在aidl中有对象的调用就要用到Parcelable(打包器)来处理。
2. 建立对象的类继承Parcelable
这里是建立一个MathFunction这样一个类,代码如下:
public class MathFunction implements Parcelable {
private int parameter;
public MathFunction() {
}
public MathFunction(Parcel myParcelable){
parameter=myParcelable.readInt();
}
public void setValue(int para){
parameter = para;
}
public int getValue(){
return parameter;
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
//将对象打包到Parcel中
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeInt(parameter);
}
public static final Parcelable.Creator<MathFunction> CREATOR = new Parcelable.Creator<MathFunction>() {
@Override
public MathFunction createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new MathFunction(source);
}
@Override
public MathFunction[] newArray(int size) {
// TODO Auto-generated method stub
return null;
}
};
}
蓝色字体的是必须继承的2个方法,//部分是我对它的理解,仅仅是个人理解,感兴趣的同学可以参考SDK官方文档或者看源代码
红色部分也是必须实现的一个静态对象,官方给出的解释是:Interface that must be implemented and provided as a public CREATOR field that generates instances of your Parcelable class from a Parcel.接口必须被实现,并且提供一个公共的CREATOR域,这个CREATOR域产生一个你的parcelable实例是从parcel类由来的。
翻译的估计不是很准,还是看看官方文档自己理解理解:
参考gen下面自动生成的IMyService.java。
当调用到calculateResult(in MathFunction myMathFunction)方法后,
if ((myMathFunction!=null)) {
_data.writeInt(1);
myMathFunction.writeToParcel(_data, 0);
}
如果myMathFunction对象不为空的时候,就在parcel的当前数据位置写上"1"并且将myMathFunction对象打包到parcel中
当数据传输时,读取parcel当前数据位置是否为0,如果不为0,就调用CREATOR.createFromParcel()方法,代码如下:
if ((0!=data.readInt())) {
_arg0 = com.android.zinc.MathFunction.CREATOR.createFromParcel(data);
}
返回一个MathFunction的一个实例。
3. 再建立一个AIDL文件
名字是MathFunction.aidl,内容如下:
package com.android.zinc;
parcelable MathFunction;
4. 建立Service
public class MyService extends Service {
private int paraA;
private int paraB;
private int paraC;
private float delta;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return mBinder;
}
private final IMyService.Stub mBinder = new IMyService.Stub(){
@Override
public float calculateResult(MathFunction myMathFunction)
throws RemoteException {
// TODO Auto-generated method stub
myMathFunction.setValue(1);
paraA=myMathFunction.getValue();
myMathFunction.setValue(-4);
paraB=myMathFunction.getValue();
myMathFunction.setValue(4);
paraC=myMathFunction.getValue();
delta=paraB*paraB-4*paraA*paraC;
return delta;
}
};
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d("zinc",">>>>>>>>>>service.OnCreate()<<<<<<<<<<");
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return super.onStartCommand(intent, flags, startId);
}
}
5. 完善客户端的程序
private ServiceConnection connection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
iMyService = (IMyService) IMyService.Stub.asInterface(service);
if(service!=null){
try {
resultDelta = iMyService.calculateResult(new MathFunction());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(resultDelta<0){
resultTextView.setText("没有实根,仅存在两个虚根");
}
else if (resultDelta == 0) {
resultTextView.setText("有2个相等的实根: ");
}
else {
resultTextView.setText("有2个不相等的实根\n");
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
以上5篇文章是我对Android Service的总结,也许有偏差或者理解错误的地方,希望高手们多多给我宝贵建议,让我不断进步,谢谢!