Android Application的做用

What is Application

Application和Actovotu,Service同樣是android框架的一個系統組件,當android程序啓動時系統會建立一個 application對象,用來存儲系統的一些信息。一般咱們是不須要指定一個Application的,這時系統會自動幫咱們建立,若是須要建立本身 的Application,也很簡單建立一個類繼承 Application並在manifest的application標籤中進行註冊(只須要給Application標籤增長個name屬性把本身的 Application的名字定入便可)。android

android系統會爲每一個程序運行時建立一個Application類的對象且僅建立一個,因此Application能夠說是單例 (singleton)模式的一個類.且application對象的生命週期是整個程序中最長的,它的生命週期就等於這個程序的生命週期。由於它是全局 的單例的,因此在不一樣的Activity,Service中得到的對象都是同一個對象。因此經過Application來進行一些,數據傳遞,數據共享 等,數據緩存等操做。緩存

 

Data passing between components using Application

假若有一個Activity A, 跳轉到 Activity B ,並須要推薦一些數據,一般的做法是Intent.putExtra() 讓Intent攜帶,或者有一個Bundle把信息加入Bundle讓Intent推薦Bundle對象,實現傳遞。但這樣做有一個問題在 於,Intent和Bundle所能攜帶的數據類型都是一些基本的數據類型,若是想實現複雜的數據傳遞就比較麻煩了,一般須要實現 Serializable或者Parcellable接口。這實際上是Android的一種IPC數據傳遞的方法。若是咱們的兩個Activity在同一個 進程當中爲何還要這麼麻煩呢,只要把須要傳遞的對象的引用傳遞過去就能夠了。app

基本思路是這樣的。在Application中建立一個HashMap<String,Object> ,以字符串爲索引,Object爲value這樣咱們的HashMap就能夠存儲任何類型的對象了。在Activity A中把須要傳遞的對象放入這個HashMap,而後經過Intent或者其它途經再把這人索引的字符串傳遞給Activity B ,Activity B 就能夠根據這個字符串在HashMap中取出這個對象了。只要再向下轉個型 ,就實現了對象的傳遞。框架

Data caching in Application

我通常會習慣在application中創建兩個HashMap<String,Object>一個用於數據的傳遞,一個用於緩 存一些數據。好比有一個Activity須要從網站獲取一些數據,獲取完以後咱們就能夠把這個數據cache到Application 當中,當頁面設置到其它Activity再回來的時候,就能夠直接使用緩存好的數據了。但若是須要cache一些大量的數據,最好是cache一些 (軟引用)SoftReference ,並把這些數據cache到本地rom上或者sd卡上。若是在application中的緩存不存在,從本地緩存查找,若是本地緩存的數據也不存在再從網 絡上獲取。網站

PitFalls

使用Application若是保存了一些不應保存的對象很容易致使內存泄漏。若是在Application的oncreate中執行比較 耗時的操做,將直接影響的程序的啓動時間。不些清理工做不能依靠onTerminate完成,由於android會盡可能讓你的程序一直運行,因此頗有可能 onTerminate不會被調用。this

MemoryLeak

在Java中內存泄漏是隻,某個(某些)對象已經不在被使用應該被gc所回收,但有一個對象持有這個對象的引用而阻止這個對象被回收。好比我 們一般會這樣建立一個View TextView tv = new TextView(this);這裏的this一般都是Activity。因此這個TextView就持有着這個Activity的引用。下面看張圖 (Google IO 2011 ppt中抄得)spa

Android筆記 <wbr>Application對象的使用-數據傳遞以及內存泄漏問題

一般狀況下,當用戶轉動手機的時候,android會從新調用OnCreate()方法生成一個新的Activity,原來的 Activity應該被GC所回收。但若是有個對象好比一個View的做用域超過了這個Activity(好比有一個static對象或者咱們把這個 View的引用放到了Application當中),這時候原來的Activity將不能被GC所回收,Activity自己又持有不少對象的引用,因此 整個Activity的內存被泄漏了。線程

常常致使內存泄漏的一些緣由:code

keeping a long-lived reference to a Context.持有一個context的對象,從而gc不能回收。component

1,一個View,的做用域超出了所在的Activity的做用域,好比一個static的View或者 把一個View cache到了application當中 etc

2,某些與View關聯的Drawable的做用域超出了Activity的做用域。

3,Runnable對象:好比在一個Activity中啓用了一個新線程去執行一個任務,在這期間這個Activity被系統回收了, 但Runnalbe的任務尚未執行完畢並持有Activity的引用而泄漏,但這種泄漏通常來泄漏一段時間,只有Runnalbe的線程執行完閉,這個 Activity又能夠被正常回收了。

4,內存類的對象做用域超出Activity的範圍:好比定義了一個內存類來存儲數據,又把這個內存類的對象傳給了其它Activity 或者Service等。由於內部類的對象會持有當前類的引用,因此也就持有了Context的引用。解決方法是若是不須要當前的引用把內部類寫成 static或者,把內部類抽取出來變成一個單獨的類,或者把避免內部對象做用域超出Activity的做用域。

out Of Memery Error 在android中每個程序所分到的內存大小是有限的,若是超過了這個數就會報Out Of Memory Error。android給程序分配的內存大小與手機硬件有關,如下是一些手機的數據:

G1:16M Droid:24 Nexus One:32M Xoom:48Ms

因此儘可能把程序中的一些大的數據cache到本地文件。以避免內存使用量超標。

Snippets

1,經過Application在兩個Activity間傳遞數據

Android筆記 <wbr>Application對象的使用-數據傳遞以及內存泄漏問題  Android筆記 <wbr>Application對象的使用-數據傳遞以及內存泄漏問題

 

記得數據傳遞完成以後,把存放在application的HashMap中的數據remove掉,以避免發生內存的泄漏。

 

 

其實咱們開發的每一個android應用程序就是一個Appliction,定義這個類每每是在AndroidManifes.xml中用到。例如:

 

<application android:icon="@drawable/icon"

    android:label="@string/app_name"

    android:name=".MyApplication">

 

這裏定義了咱們整個應用程序的屬性,例如名稱和圖標。

咱們能夠自定義Appliction,例如:

public class MyApplication extends Application {

}

就是這兒,將咱們之前一直用的默認Application給他設置成咱們本身作的MyApplicationMyApplication類的做用是爲了放一些全局的和一些上下文都要用到變量和方法之類的。

相關文章
相關標籤/搜索