把Parcel序列化到Parcelable用例

本文介绍了一种利用Parcelable接口进行跨进程通信的方法,通过创建ParaParcel类,实现了一个可以携带不同模块ID和内部Parcel的Parcelable对象,解决了在不频繁编译服务进程的情况下,多个进程间函数调用参数传递的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:

A B C三个进程,A通过B调用C的函数,通过ADIL接口,AIDL接口声明要调用的函数名称(ID)用Parcel传输要调用函数参数。
B相当于一个服务,提供给A,C两个进程,我们不希望B频繁编译。

根据需求,我们知道Parcel传递参数,经常是一个函数一个parcel文件,因为参数不一样,协议也就不同,B要求不编译,那常规做法就不能实现需求,那么,我们能不能做一个基类,然后每次把Parcel 设进去呢,答案是可以的

我们可以实现这样的parcelable

public class ParaParcel implements Parcelable {
    //class的数据
    private int moduleid;
    private Parcel innerParcel;
}

moduleid是个标识,每个函数对应一种协议

innerParcel是我们要序列化的东西

下面我附上完整的Parcelable代码

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

/**
 *
 */
public class ParaParcel implements Parcelable {
    //class的数据
    private int moduleid;
    private Parcel innerParcel;


    //为了方便,添加从parcel生成对象的构造函数

    /**
     *
     * @param source 类似于c++中的拷贝构造函数,读跟写是一一对应的
     */
    public ParaParcel(Parcel source) {
        this.moduleid = source.readInt();
        int innerSize = source.readInt();
        byte [] var = new byte[innerSize];
        source.readByteArray(var);
        this.innerParcel = Parcel.obtain();
        this.innerParcel.unmarshall(var, 0,innerSize);
        this.innerParcel.setDataPosition(0);
    }

    /**
     *
     * @param moduleid
     * @param basesParcel
     */
    public ParaParcel(int moduleid, Parcel basesParcel) {
        this.moduleid = moduleid;
        this.innerParcel = basesParcel;
    }

    /**
     *
     * @return
     */
    public int getMuleid() {
        return this.moduleid;
    }

    /**
     *
     * @return
     */
    public Parcel getBaseParcel() {
        return this.innerParcel;
    }
    //用默认实现即可
    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    //将数据写入Parcel,用于传输,写入parcel中的数据是我们要序列化的参数
    //写入的是moduleid,innerparcel用marshall函数转化为byte数组,然后
    //当成byte数组写入parcel
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // TODO Auto-generated method stub
        dest.writeInt(this.moduleid);

        byte[] var = this.innerParcel.marshall();
        dest.writeInt(var.length);
        dest.writeByteArray(var);
    }

    public void readFromParcel(Parcel dest) {
        this.moduleid = dest.readInt();//读moduleid
        int innerSize = dest.readInt();//读数据size
        byte [] var = new byte[innerSize];//读byte数组
        dest.readByteArray(var);

        this.innerParcel = Parcel.obtain();
        this.innerParcel.unmarshall(var, 0,innerSize);//将byte数据unmarshall成parcel
        this.innerParcel.setDataPosition(0);
    }
    //将数据从Parcel读出
    public static final Parcelable.Creator<ParaParcel> CREATOR = new  Parcelable.Creator<ParaParcel>() {
        @Override
        public ParaParcel[] newArray(int size) {
            return new ParaParcel[size];
        }

        //从parcel获得数据
        @Override
        public ParaParcel createFromParcel(Parcel source) {
            return new ParaParcel(source);
        }
    };
}

以上即实现了上诉需求

具体的使用

//构造parcel
Parcel b = Parcel.obtain();
b.writeInt(100);
b.writeInt(5);
ParaParcel retParcel;
//将parcel设入parcelable
ParaParcel paraParcel = new ParaParcel(1, b);
retParcel = myBinder.AccordApkNameAndFuncCallApkFunction("Vehicle_Info_apk", "Sound", paraParcel);
System.out.println(retParcel.getBaseParcel().readInt());

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

breakpoints_

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值