一、Application是什么
Application和Actovotu,Service一樣是android框架的一個系統組件,當android程序啟動時系統會創建一個 application對象,用來存儲系統的一些信息。通常我們是不需要指定一個Application的,這時系統會自動幫我們創建,如果需要創建自己 的Application,也很簡單創建一個類繼承 Application並在manifest的application標簽中進行注冊(只需要給Application標簽增加個name屬性把自己的 Application的名字定入即可)。
android系統會為每個程序運行時創建一個Application類的對象且僅創建一個,所以Application可以說是單例 (singleton)模式的一個類.且application對象的生命周期是整個程序中最長的,它的生命周期就等於這個程序的生命周期。因為它是全局 的單例的,所以在不同的Activity,Service中獲得的對象都是同一個對象。所以通過Application來進行一些,數據傳遞,數據共享 ,數據緩存等操作。
二、Application 配置全局Context
第一步、寫一個全局的單例模式的MyApplication繼承自Application 覆蓋onCreate ,在這個方法里面實例化Application
第二步、配置全局的Context
<application Android:name="com.appstore.service.MyApplication" ></application>
第三步、使用,使用的時候用的時候根據類的名稱訪問Context
三、Android程序的入口點
其實在android.app.Application這個包的onCreate才是真正的Android入口點,只不過大多數開發者無需重寫該類,他的繼承關系如下圖:
java.lang.Object
? android.content.Context
? android.content.ContextWrapper
? android.app.Application
android.app.Application類包含了4個公開的方法
void onConfigurationChanged(Configuration newConfig)
void onCreate() //這里才是真正的入口點。
void onLowMemory()
void onTerminate()
所以希望大家,記住真正的Android入口點是application的main,你可以看下androidmanifest.xml的包含關系就清楚了,並不是每個應用都必須有Activity的。
四、重寫 Application 類的生命周期事件
public void onCreate()
在應用程序創建的時候被調用,可以實現這個這個方法來創建和實例化任何應用程序狀態變量或共享資源。還可以在這個方法里面得到 Application 的單例。
public void onTerminate ()
當終止應用程序對象時調用,不保證一定被調用,當程序是被內核終止以便為其他應用程序釋放資源,那么將不會提醒,並且不調用應用程序的對象的onTerminate方法而直接終止進程。
public void onLowMemory()
當系統資源匱乏的時候,我們可以在這里可以釋放額外的內存, 這個方法一般只會在后台進程已經結束,但前台應用程序還是缺少內存時調用。可以重寫這個方法來清空緩存或者釋放不必要的資源。
public void onTrimMemory(int level)
當運行時決定當前應用程序應該減少其內存開銷時(通常在進入后台運行的時候)調用,包含一個 level 參數,用於提供請求的上下文。
public void onConfigurationChanged (Configuration newConfig)
與 Activity 不同,配置改變時,應用程序對象不會被終止和重啟。如果應用程序使用的值依賴於特定的配置,則重寫這個方法來加載這些值,或者在應用程序級處理配置值的改變。
五、數據傳遞
假如有一個Activity A, 跳轉到 Activity B ,並需要傳遞一些數據,通常的作法是 Intent.putExtra() 讓Intent攜帶,或者有一個Bundle把信息加入Bundle讓Intent傳遞Bundle對象,實現傳遞。但這樣有一個問題在於,Intent 和 Bundle 所能攜帶的數據類型都是一些基本的數據類型,如果想實現復雜的數據傳遞就比較麻煩了,通常需要實現 Serializable 或者 Parcellable 接口。這其實是Android的一種IPC數據傳遞的方法。如果我們的兩個Activity在同一個進程當中為什么還要這么麻煩呢,只要把需要傳遞的對象的引用傳遞過去就可以了。
基本思路是:在 Application 中創建一個 HashMap ,以字符串為key,Object為value這樣我們的 HashMap 就可以存儲任何類型的對象了。在Activity A中把需要傳遞的對象放入這個HashMap,然后通過 Intent 或者其它途徑再把這 key 傳遞給Activity B ,Activity B 就可以根據這個字符串在 HashMap 中取出這個對象了。只要再向下轉型 ,就實現了對象的傳遞。
六、數據共享
定義兩個Activity: MainActivity.java 和 MainActivity2.java, 代碼是一樣的
1 TextView tv; 2 EditText et; 3 4 @Override 5 protected void onCreate(Bundle savedInstanceState) { 6 super.onCreate(savedInstanceState); 7 //setContentView(R.layout.activity_main_activity2); 8 setContentView(R.layout.activity_main2); 9 10 tv = (TextView) findViewById(R.id.tv); 11 et = (EditText) findViewById(R.id.et); 12 13 tv.setText("共享數據:" + getApp().getTextData()); 14 15 findViewById(R.id.btnTextData).setOnClickListener(new OnClickListener() { 16 @Override 17 public void onClick(View v) { 18 getApp().setTextData(et.getText().toString()); 19 tv.setText("共享數據:" + et.getText().toString()); 20 } 21 }); 22 } 23 24 public App getApp() { 25 return ((App)getApplicationContext()); 26 }
定義一個類App,集成Application
1 public class App extends Application { 2 3 private String textData = "default"; 4 5 public void setTextData(String textData) { 6 this.textData = textData; 7 } 8 public String getTextData() { 9 return textData; 10 } 11 }
修改AndroidManifest.xml文件, 使用自定義的Application,兩個Activity都是入口:
1 <application 2 android:name="com.carloz.learnapplication.App" 3 android:allowBackup="true" 4 android:icon="@drawable/ic_launcher" 5 android:label="@string/app_name" 6 android:theme="@style/AppTheme" > 7 <activity 8 android:name=".MainActivity" 9 android:label="@string/app_name" > 10 <intent-filter> 11 <action android:name="android.intent.action.MAIN" /> 12 13 <category android:name="android.intent.category.LAUNCHER" /> 14 </intent-filter> 15 </activity> 16 <activity 17 android:name="com.carloz.learnapplication.MainActivity2" 18 android:label="@string/title_activity_main_activity2" > 19 <intent-filter> 20 <action android:name="android.intent.action.MAIN" /> 21 22 <category android:name="android.intent.category.LAUNCHER" /> 23 </intent-filter> 24 </activity> 25 </application>
結果,在一個Activity修改App的數據,在另一個Activity都能獲取到
七、數據緩存
在 Application 中建立兩個 HashMap 一個用於數據的傳遞,一個用於緩存一些數據。比如有一個Activity需要從網站獲取一些數據,獲取完之后我們就可以把這個數據先存到Application 當中,當頁面跳轉到其它 Activity 再回來的時候,就可以直接使用緩存好的數據了。但如果需要cache一些大量的數據,最好是cache一些 (軟引用)SoftReference ,並把這些數據cache到本地Rom 上或者 SDCard上。如果在 Application 中的緩存不存在,從本地緩存查找,如果本地緩存的數據也不存在再從網絡上獲取。