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

  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架构)。

 

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

[java] view plain copy
 
  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;)来实现:

 

[java] view plain copy
 
  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

[java] view plain copy
 
  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对象

[java] view plain copy
 
  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对象

[java] view plain copy
 
  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

[java] view plain copy
 
  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来存储数据。

 

[java] view plain copy
 
  1. public final class Bundle implements Parcelable, Cloneable {  
  2.     private static final String LOG_TAG = "Bundle";  
  3.     public static final Bundle EMPTY;  
  4.   
  5.     static {  
  6.         EMPTY = new Bundle();  
  7.         EMPTY.mMap = Collections.unmodifiableMap(new HashMap<String, Object>());  
  8.     }  
  9.   
  10.     // Invariant - exactly one of mMap / mParcelledData will be null  
  11.     // (except inside a call to unparcel)  
  12.   
  13.     /* package */ Map<String, Object> mMap = null;  
  14.   
  15.     /* 
  16.      * If mParcelledData is non-null, then mMap will be null and the 
  17.      * data are stored as a Parcel containing a Bundle.  When the data 
  18.      * are unparcelled, mParcelledData willbe set to null. 
  19.      */  
  20.     /* package */ Parcel mParcelledData = null;  

 

[java] view plain copy
 
    1.  public void putFloat(String key, float value) {  
    2.         unparcel();//首先解析出mParcelledData到mMap  
    3.         mMap.put(key, value);  
    4.     }  
    5.   
    6.    
    7. /* package */ synchronized void unparcel() {  
    8.         if (mParcelledData == null) {  
    9.             return;  
    10.         }  
    11.   
    12.         int N = mParcelledData.readInt();  
    13.         if (N < 0) {  
    14.             return;  
    15.         }  
    16.         if (mMap == null) {  
    17.             mMap = new HashMap<String, Object>();  
    18.         }  
    19.         mParcelledData.readMapInternal(mMap, N, mClassLoader);  
    20.         mParcelledData.recycle();  
    21.         mParcelledData = null;//回收以后值为null  
    22.     }  
posted @ 2016-05-03 19:53  我所向往的美好  阅读(2783)  评论(0编辑  收藏  举报