Android远程服务一:android AIDL远程服务调用

本文转载自:点击打开链接,感谢原文作者的分享,首先通过代码了解Android远程服务。

AIDL是一种远程服务调用机制,写一个简单的例子,我想应该能让大家知道它的基本使用方法。

这个例子实现的是两个应用之间的对象的数据的传递,例子比较简单,不过能体现AIDL的用法也就足够了。
  首先,如果你只需要传递比较简单的数据,比如 java原始类型数据,string charsequence 或者list/map不过list/map中的数据也必须是基本数据类型。那么可以直接传递。例如:
IService.aidl
package com.godxj.android.aidlservice;
interface IService{
String getString(intfirst);
}
保存之后,可以在gen下找到对应的java文件,这里就不说这个java中binder机制了。有兴趣可以去读读它的实现原理。
  其次,如果你需要的传递的是比较复杂的数据,那么就要对数据进行封装,而Parcelable就是一个封装工具--包嘛装数据的!例如:
IService2.aidl
package com.godxj.android.aidlservice;
import com.godxj.android.aidlservice.User;
interface IService2{
String getDouble(in String name, in User first);
}

这里的user就是一个对象,这个对象就需要用Parcelable包装一下:
package com.godxj.android.aidlservice;
 
import android.os.Parcel;
import android.os.Parcelable;
 
public class User implementsParcelable {
 
private int age;
private String name;
private String sex;
 
public int getAge() {
returnage;
}
 
public void setAge(intage) {
this.age = age;
}
 
public String getName() {
returnname;
}
 
public void setName(String name) {
this.name = name;
}
 
public String getSex() {
returnsex;
}
 
public void setSex(String sex) {
this.sex = sex;
}
 
@Override
public int describeContents() {
System.out.println("describeContents");
return0;
}
 
public static final Parcelable.Creator<User> CREATOR = newCreator<User>() {
 
@Override
public User[] newArray(intsize) {
return new User[size];
}
 
@Override
public User createFromParcel(Parcel source) {
System.out.println("createFromParcel");
User user = newUser();
user.age = source.readInt();
user.name = source.readString();
user.sex = source.readString();
return user;
}
};
 
@Override
public void writeToParcel(Parcel dest, intflags) {
System.out.println("writeToParcel");
dest.writeInt(age);
dest.writeString(name);
dest.writeString(sex);
}
 
}

当然,这个Parcelable,就是刚才说的装包,writeToParcel这个方法就是装包啦,而Creator里面的createFromParcel这个方法相当于就是解包了。 
重点:
1.在装包的时候装(writeToParcel)的先后顺序,要和解包(createFromParcel)的先后顺序保持一致,不然可能出现数据位置互换的错。
2.每一个被包装(实现了Parcelable)的对象都需要一个单独的aidl文件,如:
User.aidl
package com.godxj.android.aidlservice;
parcelable User;

3.每一个aidl文件中出现的被包装的类都需要引入他所在的包,如:import com.godxj.android.aidlservice.User;

4.作为服务程序的那个service,必须要一个匹配的action,如果需要其他的action可以添加在他的后面。如:

<service android:name="com.godxj.android.aidlservice.AIDLServiceImp">
<intent-filter >
<action android:name="com.godxj.android.aidlservice.IService"/>
<action android:name="com.godxj.android.aidlservice.action"/>
</intent-filter>
</service>


5.客户端需要用到的所有内容,都需要从服务端拷贝过去,如下面两个目录结构:
     服务端                            客户端

  最后一点,也就是代码的实现中。理解起来也不难。

既然是作为服务端,那么必然有一个实现了android.app.service的service,对于大家都知道,启动service可以通过startService也可以通过bindService来启动,而aidl需要使用后者,绑定服务--onBind。可以看到,在这里便是返回一个IBinder给启用它的activity,那么这里返回的,很容易相到就是我们的服务内容了。但是这个返回的IBinder在哪里呢,这个类就是我们编写的aidl服务后,android自己为我们生成的一个IBinder了。在gen目录下可以找到与编写的aidl对应的服务java文件,例如:

public interface IService2 extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements
com.godxj.android.aidlservice.IService2


可以看到,在IService2里面 出现了一个抽象类Stub,而它就是我们需要的IBinder,同时我们也看到了它继承了android.os.Binder。

那么现在就好办了,实例化这个抽象类返回回去,例如:

public class Service2Imp extends IService2.Stub{
@Override
public String getDouble(String name, User first) throwsRemoteException {
System.out.println("....................");
System.out.println(" the name = " + name);
System.out.println("age = " + first.getAge());
System.out.println("name = " + first.getName());
System.out.println("sex = " + first.getSex());
return"second";
}
}


那么服务端就算是ok了。

  最后客户端,在启用它的时候使用bindService,而在这里bindService(Intent service,ServiceConnection conn, int flags);可以看到第一和第三个参数都知道什么含义,第二个参数其实就是服务连接操作,可以理解为练上了service然后做什么。既然它需要这样一个对象,那么我们就实例这样一个对象给它,事实上我们实例化之后,正如其名,它就是给我们提供一个练上了干什么,断开了又干什么两个方法。例如:

private ServiceConnection serCon = new ServiceConnection() {
 
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("onServiceDisconnected");
}
 
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("onServiceConnected");
// iservice = IService.Stub.asInterface(service);
iservice2 = IService2.Stub.asInterface(service);
try{
// System.out.println(iservice.getString(10));
User user = new User();
user.setAge(22);
user.setName("godxj");
user.setSex("boy");
iservice2.getDouble("Are You !", user);
}catch(Exception e) {
e.printStackTrace();
}
}
};


  到这里,AIDL的实现就算是完成了,当然我还是得提醒下,这个服务启动了一定要记得关!unBind还是要的。如:

protected void onDestroy() {
super.onDestroy();
unbindService(serCon);
}

还有两个工程源码附件,可惜CSDN不支持上传。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值