AIDL第二篇,主要记录一下自己学习AIDL自定义类型数据的过程,如下:
服务端目录结构:
客户端目录结构:
接下来是具体代码:
AIDL文件:
// IMyAidlInterface.aidl
package com.sjq.aidlservice;
// Declare any non-default types here with import statements
import com.sjq.aidlservice.Persion;
interface IMyAidlInterface {
//此处用到的实体类一要手动倒包,二要声明AIDL文件并在AIDL文件中声明类型
List<Persion> addPersion(in Persion p);
}
因为要用到自定义的类型,所以这个类型也必须新建AIDL文件
// IMyAidlInterface.aidl
package com.sjq.aidlservice;
//声明类型
parcelable Persion;
Service代码实现:
package com.sjq.aidlservice;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;
public class MyService extends Service {
ArrayList<Persion> list ;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
list = new ArrayList<>();
return binder;
}
IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
@Override
public List<Persion> addPersion(Persion p) throws RemoteException {
list.add(p);
return list;
}
};
}
最后是实体类代码,实现Parceable接口
package com.sjq.aidlservice;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by cs001 on 2016/6/28.
*/
public class Persion implements Parcelable {
private String name;
private int age;
private String adrs;
protected Persion(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
this.adrs = in.readString();
//如果此类中有另外一个自定义的类型,由于Book是另外一个可序列化对象,所以它的反序列化需要传递当前线程的上下文类加载器
// 否则会报类无法找到的异常
// this.book = in.readParceable(Thread.currentThread().getContextClassLoader());
}
/**
* @param dest Parcel 内部封装了可序列化的数据,可以在Binder中自由传输
* @param flags 0或者1 为1时,当前对象需要作为返回值返回,不能立即释放资源,几乎所有情况都为0
* 对象的序列化工作主要由此函数完成
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
dest.writeString(adrs);
}
/**
* 内容描述功能由此函数功能,仅当当前对象中存在文件描述符时返回1,
* 几乎所有情况下都返回0
*
* @return
*/
@Override
public int describeContents() {
return 0;
}
/**
* 反序列化工作主要由CREATOR完成
*/
public static final Creator<Persion> CREATOR = new Creator<Persion>() {
@Override
public Persion createFromParcel(Parcel in) {
return new Persion(in);
}
@Override
public Persion[] newArray(int size) {
return new Persion[size];
}
};
@Override
public String toString() {
return "Persion{" +
"adrs='" + adrs + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
接下来是客户端代码:
同样的还是要把AIDL文件和实体类复制到客户端,包名要完全相同
如下:
代码:
package com.sjq.aidl;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import com.sjq.aidlservice.IMyAidlInterface;
import com.sjq.aidlservice.Persion;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private IMyAidlInterface iMyAidlInterface;
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//将Binder转换为服务端的接口对象
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.add_btn);
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.sjq.aidlservice", "com.sjq.aidlservice.MyService"));
bindService(intent, conn, BIND_AUTO_CREATE);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
List<Persion> persions = iMyAidlInterface.addPersion(new Persion("张三",18,"宇宙中心五道口"));
Log.i("TAG", persions.toString());
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
以上就是全部代码,主要是跨进程通信传输自定义类型的数据