Activity之間傳遞數據的方式及常見問題總結

轉載:大飛 http://blog.csdn.net/rflyee/article/details/47431633html

Activity之間傳遞數據通常經過如下幾種方式實現:
1. 經過intent傳遞數據
2. 經過Application
3. 使用單例
4. 靜態成員變量。(能夠考慮  WeakReferences
5. 持久化(sqlite、share preference、file等)
 
1、經過intent傳遞數據
(1)直接傳遞,intent.putExtra(key, value)
(2)經過bundle,intent.putExtras(bundle);
TL:
(1)這兩種都要求傳遞的對象必須可序列化( Parcelable、Serializable)
(2)Parcelable實現相對複雜
(3)關於Parcelable和Serializable,官方說法:
         Serializable: it's error prone and horribly slow. So in general: stay away from  Serializable if possible.
     也就是說和Parcelable相比,Seriaizable容易出錯而且速度至關慢。是否這樣,可參見 下一篇博客說明。

(4)經過intent傳遞數據是有大小限制滴,超過限制,要麼拋異常,要麼新的Activity啓動失敗,因此仍是很嚴重的啊,可參見下一篇博客說明。android

 
2、Application
   這個應該也都接觸過,將數據保存早全局Application中,隨整個應用的存在而存在,這樣不少地方都能訪問。具體使用就很少說了。
可是須要 注意的是:
  當因爲某些緣由(好比系統內存不足),咱們的app會被系統強制殺死,此時再次點擊進入應用時,系統會直接進入被殺死前的那個界面,製造一種歷來沒有被殺死的假象。那麼問題來了,系統強制中止了應用,進程死了,那麼再次啓動時Application天然新的,那裏邊的數據天然木有啦,若是直接使用極可能報空指針或者其餘錯誤。
  所以仍是要考慮好這種狀況的:
  (1)使用時必定要作好非空判斷
  (2)若是數據爲空,能夠考慮邏輯上讓應用直接返回到最初的activity,好比用  FLAG_ACTIVITY_CLEAR_TASK 或者  BroadcastReceiver 殺掉其餘的activity。
 
3、使用單例
好比一種常見的寫法:
public class DataHolder {
  private String data;
  public String getData() {return data;}
  public void setData(String data) {this.data = data;}
  private static final DataHolder holder = new DataHolder();
  public static DataHolder getInstance() {return holder;}
}
這樣在啓動activity以前:
DataHolder.getInstance().setData(data);
新的activity中獲取數據:
String data = DataHolder.getInstance().getData();
4、靜態Statis
這個能夠直接在activity中也能夠單獨一個數據結構體,就和單例差很少了。
好比:
public class DataHolder {
  private static String data;
  public static String getData() {return data;}
  public static String setData(String data) {this.data = data;}
}
啓動以前設置數據,新的activity獲取數據。
 
注意:這些狀況若是數據很大不少,好比bitmap,處理不當是很容易致使內存泄露或者內存溢出的。
因此能夠考慮使用WeakReferences 將數據包裝起來。
好比:
public class DataHolder {
  Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();

  void save(String id, Object object) {
    data.put(id, new WeakReference<Object>(object));
  }

  Object retrieve(String id) {
    WeakReference<Object> objectWeakReference = data.get(id);
    return objectWeakReference.get();
  }
}
啓動以前:
DataHolder.getInstance().save(someId, someObject);
新activity中:
DataHolder.getInstance().retrieve(someId);
這裏可能須要經過intent傳遞id,若是數據惟一,id均可以不傳遞的。save() retrieve()中id都固定便可。
 
5、持久化數據
那就是sqlite、share preference、file等了。
優勢:
(1)應用中全部地方均可以訪問
(2)即便應用被強殺也不是問題了
缺點:
(1)操做麻煩
(2)效率低下
(3)io讀寫嘛,其實仍是比較容易出錯的
相關文章
相關標籤/搜索