Parcelable

2018-12-07  本文已影响6人  汇源可乐

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;
}


上一篇下一篇

猜你喜欢

热点阅读