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

时间:2021-10-27 23:47:08
  1. public class Intent implements Parcelable, Cloneable {   //... private String mAction;
  2. private Uri mData;
  3. private String mType;
  4. private String mPackage;
  5. private ComponentName mComponent;
  6. private int mFlags;
  7. private HashSet<String> mCategories;
  8. private Bundle mExtras;
  9. private Rect mSourceBounds;

转自:http://blog.csdn.net/annkie/article/details/8483253

Intent也是继承了Parcelable的接口。

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

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

  1. Intent putExtra(String name, int[] value)
  2. Intent putExtra(String name, float value)
  3. Intent putExtra(String name, byte[] value)
  4. Intent putExtra(String name, long[] value)
  5. Intent putExtra(String name, float[] value)
  6. Intent putExtra(String name, long value)
  7. Intent putExtra(String name, String[] value)
  8. Intent putExtra(String name, boolean value)
  9. Intent putExtra(String name, boolean[] value)
  10. Intent putExtra(String name, short value)
  11. Intent putExtra(String name, double value)
  12. Intent putExtra(String name, short[] value)
  13. Intent putExtra(String name, String value)
  14. Intent putExtra(String name, byte value)
  15. Intent putExtra(String name, char[] value)
  16. Intent putExtra(String name, CharSequence[] value)

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

  1. public Intent putExtra(String name, long value) {
  2. if (mExtras == null) {
  3. mExtras = new Bundle();
  4. }
  5. mExtras.putLong(name, value);
  6. return this;
  7. }

第二类:传递一个Bundle

  1. public Intent putExtra(String name, Bundle value) {
  2. if (mExtras == null) {
  3. mExtras = new Bundle();
  4. }
  5. mExtras.putBundle(name, value);
  6. return this;
  7. }

第三类:传递Serializable对象

  1. public Intent putExtra(String name, Serializable value) {
  2. if (mExtras == null) {
  3. mExtras = new Bundle();
  4. }
  5. mExtras.putSerializable(name, value);
  6. return this;
  7. }

第四类:Parcelable对象

  1. public Intent putExtra(String name, Parcelable value) {
  2. if (mExtras == null) {
  3. mExtras = new Bundle();
  4. }
  5. mExtras.putParcelable(name, value);
  6. return this;
  7. }
  8. public Intent putExtra(String name, Parcelable[] value) {
  9. if (mExtras == null) {
  10. mExtras = new Bundle();
  11. }
  12. mExtras.putParcelableArray(name, value);
  13. return this;
  14. }

第五类:Intent

  1. public Intent putExtras(Intent src) {
  2. if (src.mExtras != null) {
  3. if (mExtras == null) {
  4. mExtras = new Bundle(src.mExtras);
  5. } else {
  6. mExtras.putAll(src.mExtras);
  7. }
  8. }
  9. return this;
  10. }

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

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

mParcelledData

两者同时只有一个有效。

一旦unparcel以后,mParcelledData

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

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

  1. public final class Bundle implements Parcelable, Cloneable {
  2. private static final String LOG_TAG = "Bundle";
  3. public static final Bundle EMPTY;
  4. static {
  5. EMPTY = new Bundle();
  6. EMPTY.mMap = Collections.unmodifiableMap(new HashMap<String, Object>());
  7. }
  8. // Invariant - exactly one of mMap / mParcelledData will be null
  9. // (except inside a call to unparcel)
  10. /* package */ Map<String, Object> mMap = null;
  11. /*
  12. * If mParcelledData is non-null, then mMap will be null and the
  13. * data are stored as a Parcel containing a Bundle.  When the data
  14. * are unparcelled, mParcelledData willbe set to null.
  15. */
  16. /* package */ Parcel mParcelledData = null;
    1. public void putFloat(String key, float value) {
    2. unparcel();//首先解析出mParcelledData到mMap
    3. mMap.put(key, value);
    4. }
    5. /* package */ synchronized void unparcel() {
    6. if (mParcelledData == null) {
    7. return;
    8. }
    9. int N = mParcelledData.readInt();
    10. if (N < 0) {
    11. return;
    12. }
    13. if (mMap == null) {
    14. mMap = new HashMap<String, Object>();
    15. }
    16. mParcelledData.readMapInternal(mMap, N, mClassLoader);
    17. mParcelledData.recycle();
    18. mParcelledData = null;//回收以后值为null
    19. }