Android:Intent传递数据的几种类型和源码实现

 

public class Intent implements Parcelable, Cloneable {   //... private String mAction;
    private Uri mData;
    private String mType;
    private String mPackage;
    private ComponentName mComponent;
    private int mFlags;
    private HashSet<String> mCategories;
    private Bundle mExtras;
    private Rect mSourceBounds;
Intent也是继承了Parcelable的接口。

个人理解,Intent应该只是一个数据参数的载体,真正将两个Acitivity/Service通信起来的是Binder接口(C/S架构)。


第一类:简单或基本数据类型

Intent putExtra(String name, int[] value)
Intent putExtra(String name, float value)
Intent putExtra(String name, byte[] value)
Intent putExtra(String name, long[] value)
Intent putExtra(String name, float[] value)
Intent putExtra(String name, long value)
Intent putExtra(String name, String[] value)
Intent putExtra(String name, boolean value)
Intent putExtra(String name, boolean[] value)
Intent putExtra(String name, short value)
Intent putExtra(String name, double value)
Intent putExtra(String name, short[] value)
Intent putExtra(String name, String value)
Intent putExtra(String name, byte value)
Intent putExtra(String name, char[] value)
Intent putExtra(String name, CharSequence[] value)

本质上仍然是通过一个Bundle(private Bundle mExtras;)来实现:

   public Intent putExtra(String name, long value) {
        if (mExtras == null) {
            mExtras = new Bundle();
        }
        mExtras.putLong(name, value);
        return this;
    }

 第二类:传递一个Bundle

public Intent putExtra(String name, Bundle value) {
        if (mExtras == null) {
            mExtras = new Bundle();
        }
        mExtras.putBundle(name, value);
        return this;
    }

 第三类:传递Serializable对象

public Intent putExtra(String name, Serializable value) {
        if (mExtras == null) {
            mExtras = new Bundle();
        }
        mExtras.putSerializable(name, value);
        return this;
    }

 第四类:Parcelable对象

public Intent putExtra(String name, Parcelable value) {
        if (mExtras == null) {
            mExtras = new Bundle();
        }
        mExtras.putParcelable(name, value);
        return this;
}
public Intent putExtra(String name, Parcelable[] value) {
        if (mExtras == null) {
            mExtras = new Bundle();
        }
        mExtras.putParcelableArray(name, value);
        return this;
    }

第五类:Intent

 public Intent putExtras(Intent src) {
        if (src.mExtras != null) {
            if (mExtras == null) {
                mExtras = new Bundle(src.mExtras);
            } else {
                mExtras.putAll(src.mExtras);
            }
        }
        return this;
    }

归根结底都是通过Bundle来实现数据封装。而Bundle则是通过Map的数据结构来存储数据。

mMap = new HashMap<String, Object>();

mParcelledData

两者同时只有一个有效。

一旦unparcel以后,mParcelledData

的数据将被填充到mMap中,同时值为null。在writeToParcel和readFromParcel中则直接使用mParcelledData.此时一般通过IBinder关联两个进程的通信。



关于Bundle则是实现了Parcelable接口的类,通过上面提到的HashMap和一个Parcel来存储数据。

public final class Bundle implements Parcelable, Cloneable {
    private static final String LOG_TAG = "Bundle";
    public static final Bundle EMPTY;

    static {
        EMPTY = new Bundle();
        EMPTY.mMap = Collections.unmodifiableMap(new HashMap<String, Object>());
    }

    // Invariant - exactly one of mMap / mParcelledData will be null
    // (except inside a call to unparcel)

    /* package */ Map<String, Object> mMap = null;

    /*
     * If mParcelledData is non-null, then mMap will be null and the
     * data are stored as a Parcel containing a Bundle.  When the data
     * are unparcelled, mParcelledData willbe set to null.
     */
    /* package */ Parcel mParcelledData = null;

 public void putFloat(String key, float value) {
        unparcel();//首先解析出mParcelledData到mMap
        mMap.put(key, value);
    }

 
/* package */ synchronized void unparcel() {
        if (mParcelledData == null) {
            return;
        }

        int N = mParcelledData.readInt();
        if (N < 0) {
            return;
        }
        if (mMap == null) {
            mMap = new HashMap<String, Object>();
        }
        mParcelledData.readMapInternal(mMap, N, mClassLoader);
        mParcelledData.recycle();
        mParcelledData = null;//回收以后值为null
    }



  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中可以使用 Bundle 对象传递数据,而 Intent 中也可以使用 Bundle 对象来传递数据。如果需要传递的数据过大,可以考虑将数据进行分割,然后再使用 Intent 传递。以下是一种实现方式: 1. 将需要传递的数据分割成若干个小数据块。可以根据数据类型和数据大小来确定分割的方式。 2. 将每个小数据块都封装成一个 Bundle 对象,并设置一个标识符,用于标识这个小数据块所属的数据。 3. 将所有的小数据块的 Bundle 对象放入一个 ArrayList 中,然后将这个 ArrayList 封装成一个新的 Bundle 对象,作为 Intent 的一个额外参数进行传递。 4. 在接收 Intent 的地方,首先获取这个额外参数,然后解析出所有的小数据块 Bundle 对象,并根据标识符将它们组合成一个完整的数据对象。 具体实现可以参考以下代码: ```java // 发送 IntentIntent intent = new Intent(context, TargetActivity.class); ArrayList<Bundle> dataBundles = splitData(data); // 将数据分割成若干个小数据块 Bundle bundle = new Bundle(); bundle.putParcelableArrayList("data", dataBundles); // 将所有小数据块封装成一个 Bundle 对象 intent.putExtras(bundle); startActivity(intent); // 接收 IntentIntent intent = getIntent(); Bundle bundle = intent.getExtras(); if (bundle != null) { ArrayList<Bundle> dataBundles = bundle.getParcelableArrayList("data"); // 获取所有小数据块的 Bundle 对象 Data data = combineData(dataBundles); // 将所有小数据块组合成完整的数据对象 // 处理数据 } ``` 需要注意的是,分割数据时需要考虑数据的完整性和顺序,以确保数据能够正确地组合成完整的数据对象。同时,也需要注意在传输过程中数据的大小,避免出现数据过大而导致传输失败的情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值