美文网首页
Parcelable

Parcelable

作者: 汇源可乐 | 来源:发表于2018-12-07 21:22 被阅读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;
    }
    
    
    

    相关文章

      网友评论

          本文标题:Parcelable

          本文链接:https://www.haomeiwen.com/subject/wmixhqtx.html