Parcelable
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
public String userId;
public String userName;
public int age;
public User(String userId, String userName, int age) {
this.userId = userId;
this.userName = userName;
this.age = age;
}
private User(Parcel in)
{
this.userId=in.readString();
this.userName=in.readString();
this.age=in.readInt();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(userId);
dest.writeString(userName);
dest.writeInt(age);
}
public static final Parcelable.Creator<User> CREATOR= new Creator<User>() {
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
}
AIDL
{Android Interface Defined Language}
User.aidl
package cn.ololee.ui;
parcelable User;//注意没有申明接口
//而且User.aidl与User.java名字必须一样
//否则会报错
//Process 'command 'D:\SDK\build-tools\27.0.3\aidl.exe'' finished with
// non-zero exit value 1
/*出现上述的错误原因:1.自己在User.aidl里面申明了接口;2当前编译版本与工具版本不一致
*/
IUserManger.aidl
package cn.ololee.ui;
import cn.ololee.ui.User;//这个特别重要
interface IUserManger {
void printUserInfo(in User user);
}
读取对象的时候需要这么写,得到当前线程的ContextClassLoader
对象=in.readParcelable(Thread.currentThread().getContextClassLoader());
完成之后仅需要Ctrl+F9,系统会自动为我们写一个IUserManger.java
IUserManger实际上是一个Binder类,该类继承自android.os.IInterface,并且自身也是一个接口类
该类有我们之前在IUserManger中写的printUserInfo(User user)方法,并且还有对应的整型Id来标识这个方法;如果有多个方法时,则id用于标识在transact过程中客户端请求的究竟是哪一个方法。
除此之外,该类还包含一个内部类Stub{Binder类}
{当客户端与服务端在同一个进程时,方法不会调用跨进程的transact过程,而当不在同一个进程时,方法调用需要走transcat过程,这个逻辑由Stub类的内部类的代理类Proxy来完成。
}
{说明:可以在Binder中传输的接口都需要继承IInterface接口}
/*
*此文件自动生成,请勿修改,源自对IUserManger.aidl的拓展
*此类的函数说明:
* 0x01:Stub抽象类{继承自Binder,引用了IUserManger的接口}
* 0x02:我们在AIDL里面申明的方法
*/
package cn.ololee.ui;
public interface IUserManger extends IInterface
{
/*
*0x01:DESCRIPTOR,Binder类的唯一标识,用当前类的类名来赋值
*0x02:Stub(),构造函数
*0x03:IUserManger asInterface(IBinder obj)将服务端的Binder对象转换为客户端所需要的AIDL接口类型的对象
*0x04:IBinder asBinder(),返回当前Binder对象
*0x05:boolean onTransact(int code,Parcel data,Parcel reply,int flags) throws RemoteExcepition
*Transact方法,运行在服务端的Binder线程池中;客户端发起进程请求时,远程请求会通
*过系统底层封装后交由此方法处理
*0x06:class Proxy implements IUserManger{代理类,引用IUserManger的接口}
*0x07:int TRANSACTION_printUserInfo=IBinder.FIRST_CALL_TRANSACTION + 0 用于标识我们在AIDL中申明的方法的整数
*/
public static abstract class Stub extends Binder implements IUserManger
{
private static final String DESCRIPTOR = "cn.ololee.ui.IUserManger";
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/*
*此函数用于将将服务端的Binder对象转换为客户端所需要的AIDL接口类型的对象
*IBinde obj 来自服务端的Binder对象
*
*如果客户端与服务端在同一个进程里
* 返回服务端的Stub对象本身
*否则
* 返回系统封装后的Stub.proxy对象
*/
public static IUserManger asInterface(IBinder obj)
{
if ((obj==null))
return null;
aIInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof IUserManger)))
{
return ((IUserManger)iin);
}
return new IUserManger.Stub.Proxy(obj);
}
@Override
public IBinder asBinder()
{
return this;
}
@Override
public boolean onTransact(int code,Parcel data,Parcel reply,int flags)throws RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_printUserInfo:
{
data.enforceInterface(DESCRIPTOR);
User _arg0;
if ((0!=data.readInt())) {
_arg0 = User.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
this.printUserInfo(_arg0);
reply.writeNoException();
return true;
}
}
return super.onTransact(code,data,reply,flags);
}
private static class Proxy implements IUserManger
{
private IBinder mRemote;
Proxy(IBinder remote)
{
mRemote = remote;
}
@Override
public IBinder asBinder()
{
return mRemote;
}
public String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override
public void printUserInfo(User user) throws RemoteException
{
Parcel _data =Parcel.obtain();
Parcel _reply =Parcel.obtain();
try
{
_data.writeInterfaceToken(DESCRIPTOR);
if ((user!=null)) {
_data.writeInt(1);
user.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_printUserInfo, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_printUserInfo=IBinder.FIRST_CALL_TRANSACTION + 0;
}
public void printUserInfo(User user) throws RemoteException;
}