Android如何通过parcelable实现跨进程之间多态的类型的传递。

一个后台服务,提供一个接口,想要利用上层的应用传递下来的数据,进行处理。但是这类数据种类繁多,该怎么办呢?Android 提供的parcelable将这些数据传递给世界的另一边。之前看了网络上的做法,有一篇文章无限接近实现了,但是由于部分错误,导致了我一直是失败的,后来自己经过摸索才终于找到原因。废话不多说,讲讲干货。

假设我们在服务端有多个数据Bean,如ABean, BBean,CBean等待传输,那么就让他们愉快的去继承一个RootBean的抽象类,记住这里的父类一定要是抽象类,否则后面会让你生不如死。多态的核心就是这个抽象类(这里千万不要去实现Creator交给他的儿子吧)

import android.os.Parcel;
import android.os.Parcelable;

public abstract class RootBean implements Parcelable {
    @Override
    public void writeToParcel(Parcel dest, int flags) {
    }

    protected RootData(Parcel in) {
    }

    protected RootData() {

    }

}

看看ABean是怎么继承它爸爸的

import android.os.Parcel;

public class ABean extends RootBean {
    int childData;

    public int getChildData() {
        return childData;
    }

    public void setChildData(int childData) {
        this.childData = childData;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeInt(this.childData);
    }

    public ChildData() {
        super();
    }

    protected ChildData(Parcel in) {
        super(in);
        this.childData = in.readInt();

    }

    public static final Creator<ChildData> CREATOR = new Creator<ChildData>() {
        public ChildData createFromParcel(Parcel in) {
            return new ChildData(in);
        }

        public ChildData[] newArray(int size) {
            return new ChildData[size];
        }
    };
}

很简单,没有什么难度,按照通用的parcelable的自动生成方式就可以了。

服务器端提供了一个,且有且仅有一个接口传递数据,这个接口的参数只能有一个,按照上面的设计思路,这里我们想传一个父类(RootBean)到世界的尽头,在世界的尽头根据"多态"再来动态生成相应的儿子对象。

为了实现上面的想法,我们这里需要一个Wrapper类来包装下自己,以便于自己能够被传输出去。

public class DataWrapper implements Parcelable {

    private RootBea rootBean;

    public RootData getRootBean() {
        return rootBean;
    }

    public void setRootBean(RootData rootBean) {
        this.rootBean= rootDean;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(this.rootData, flags);
    }

    public DataWrapper() {
    }

    protected DataWrapper(Parcel in) {
        this.rootBean = in.readParcelable(RootData.class.getClassLoader());//关键
    }

    public static final Creator<DataWrapper> CREATOR = new Creator<DataWrapper>() {
        @Override
        public DataWrapper createFromParcel(Parcel source) {
            return new DataWrapper(source);
        }

        @Override
        public DataWrapper[] newArray(int size) {
            return new DataWrapper[size];
        }
    };
}
这里的关键就是
 this.rootBean = in.readParcelable(RootBean.class.getClassLoader());

这个是parcelable获取对象的类,如果没有这句什么也白搭,如果父类不是抽象,这里也没用。

有人会问,如果这个数据到了上面,我怎么判断到底是啥类型的数据,这里可以在这个Wrapper类里面加个属性比如type或者啥的,具体怎么写就不在这里描述了,很简单,和普通的parcelable加一个属性一样。

下面讲讲怎么发送这个数据吧。

由于需要传递一个对象类型的数据而非通用类型的数据,这里需要声明一个和DataWrapper.java类同名的一个对象AIDL文件

// IDataWrapper.aidl
package com.hxcode.polymorphism;

// Declare any non-default types here with import statements

parcelable DataWrapper;

注意包名和DataWrapper.java要一致,注意包名要一致,注意包名要一致,重要的事情说三遍。

下面就是后台服务定义的一个讨要数据的接口了(我不是要饭的)

package com.hxcode.polymorphism;

// Declare any non-default types here with import statements
import com.hxcode.polymorphism.DataWrapper;

interface IRemoteService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void getData(in DataWrapper data);
}
这个接口定义了,那就需要实现他
public class ServiceImpl extends IRemoteService.Stub {

    private final static String TAG = "ServiceImpl";

    @Override
    public void sendData(DataWrapper dataWrapper) throws RemoteException {
        ABean childData = (ABean) dataWrapper.getRootBean();
        int data = childData.getChildData();//get child data
        Log.d(TAG, "send data is:"+data);
    }
}

如何调用定义的这个AIDL定义的接口?

这里不再写如何实现的,无非就是先绑定service,然后再获取IBinder等等标准的做法。

这里需要提到一点的是,有的时候,有些数据类型的有些属性是一致的,假设ABean, BBean, CBean都有名称name和地址address这些,那么我们可以再抽出一个父类。继承关系如下:






展开阅读全文

没有更多推荐了,返回首页