Android清單文件詳解(三)----應用程序的根節點<application>
1.
一般來說,在生成Android應用程序的時候,默認的AndroidManifest.xml文件中就已經包含了一些默認的
android:backupAgent="string" android:debuggable=["true"|"false"]; android:description="string resource" android:enabled=["true"|"false"] android:hasCode=["true"|"false"] android:hardwareAccelerated=["true"|"false"] android:icon="drawable reource" android:killAfterRestore=["true"|"false"] android:label="string resource" android:logo="drawable resource" android:manageSpaceActivity="string" android:name="string" android:permission="string" android:persistent=["true"|"false"] android:process="string" android:restoreAnyVersion=["true"|"false"] android:taskAffinity="string" android:theme="resource or theme">
2.如何實現Application類
首先要介紹的是android:name屬性,它指的是Application類的子類,當應用程序進程被啟動的時候,由android:name屬性指定的類將會在所有應用程序組件(activity,服務,廣播接收器,內容提供者)被實例化之前實例化。
一般情況下,應用程序無需指定這個屬性,Android會實例化Android框架下的applicaiton類。
然而,在一些特殊的情況下,比如希望在應用程序組件啟動之前就完成一個初始化工作,或者在系統低內存的時候做一些特別的處理,就要考慮實現自己的Application類的一個子類。
在Android系統提供的系統應用中,就有一個實現了自己的Application實例,這個應用程序就是Launcher。我們可以仿照它來實現一個自己的Application類,具體步驟如下。
①創建一個叫做ApplicationTest的項目,并且在默認生成的MainActivity里的onCreate()方法中添加一行代碼來輸出一條日志。這樣就可以看到Application創建時間,具體代碼如下:
public class MainActivity extends Activity { private static final String TAG="MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e(TAG,"MainActivity is created"); } }
②實現自己的MyApplication類,代碼如下:
public class MyApplication extends Application { private static final String TAG="MyApplication"; @Override public void onCreate() { super.onCreate(); Log.e(TAG,"MyApplication is created"); } }
③將MyApplication添加到清單文件AndroidManifest.xml中
從圖中可以看出來,Android先創建的MyApplication,最后才創建的MainActivity。
3.Application提供的函數及其用法
android.app.Application類提供了許多類似onCreate()的方法,它們會在不同的場景下被Android框架回調。與此同時,Application類還提供了一些監控的函數,用于監視本應用中組件的生命周期。如下表所示:
接下來,我們通過一些實例來說明如何使用這些方法和接口
①使用onConfigurationChanged()方法監聽系統配置更新
onConfigurationChanged()方法的函數原型如下:
public void?onConfigurationChanged(Configuration newConfig){}其中newConfig參數表示新的設備配置
onConfigurationChanged()方法是一個回調接口,在設備配置發生變化時由Android系統調用。與此同時,Android系統會通過參數(newConfig)傳給應用程序,由應用程序處理這個變化。注意,不同于Activity,其他組件在一個配置改變時從不重新啟動,它們孫弱自己處理改變的結果。這里所述的“配置”如下表所示:
下面我們通過一個實例來說明當設備配置發生變化的時候,系統如何通過onConfigurationChanged回調接口來通知應用程序的。
㈠為前面的應用程序添加一個名叫ConfigApplication的Application的子類,并實現onCreate()方法及onConfigurationChanged()方法。在onCreate()方法中,我們會獲取應用程序在創建之初所擁有的配置信息。而在onConfigurationChanged()方法中,則可以添加一些代碼以便用日志的方式來實時體現配置更新。相關代碼如下:
public class ConfigApplication extends Application { private static final String TAG="ConfigApplication"; private Configuration mConfiguration; @Override public void onCreate() { super.onCreate(); this.mConfiguration=getResources().getConfiguration();//獲取配置信息 Log.e(TAG,"onCreate::infomation:orientation="+this.mConfiguration.orientation); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); //打印更新后的配置信息 Log.e(TAG,"onConfigurationChanged:infomation:orientation="+newConfig.orientation); } }
㈡按前文所述,將ConfigApplication配置到AndroidManifest.xml文件中。
㈢設備運行應用程序,就可以看到如下的日志信息了。
對于日志,說明如下:
日志信息的第一行是初始狀態下的方向配置,通過上圖我們知道最初的方向值是1。而根據前面的表,可知當前是豎屏方向。
日志信息的第五行是切換橫屏后,Android系統回調了我們實現的onConfigurationChanged()方法,這時系統配置已經發生了改變,因此這里的日志打印了當前的屏幕方向是2,也是就橫屏。
建議:由于基類onConfigurationChanged()方法中實現了對一些回調接口的調用,所以如果我們重寫了這個方法,那么為了維持原Application類的行為,建議在重寫的方法入口調用super.onConfigurationChanged(newConfig)。
②使用onCreate()完成應用程序初始化
onCreate()方法的原型為:
public void onCreate(){}
如前面的表所示,onCreate()方法是一個回調接口。Android系統會在應用程序啟動的時候,在任何應用程序組件(Activity,服務,廣播接收器,內容提供者)被創建之前調用這個接口。
需要注意的是,這個方法的執行效率會直接影響到啟動Activity,服務,廣播接收器,或者內容提供者的性能,因此該方法應盡可能快地完成。
最后,如果實現了這個回調接口,請前晚不要忘記調用super.onCreate(),否則應用程序會報錯。
前面我們實現了Appplication類的子類------Configuration,并且也已經實現了自身的onCreate()方法。這里來做個小實驗,讓大家更清楚這些知識。
現在,在源代碼的onCreate()方法中加入一個大約20秒的等待,以此來模擬在onCreate()方法中做了過于繁重的工作而導致該方法長時間無法完成的情況,修改后的代碼如下:
public class ConfigApplication extends Application { private static final String TAG="ConfigApplication"; private Configuration mConfiguration; @Override public void onCreate() { super.onCreate(); this.mConfiguration=getResources().getConfiguration();//獲取配置信息 Log.e(TAG,"onCreate::infomation:orientation="+this.mConfiguration.orientation); SystemClock.sleep(20000);//沉睡20秒 } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); //打印更新后的配置信息 Log.e(TAG,"onConfigurationChanged:infomation:orientation="+newConfig.orientation); } }
此時運行程序,程序就會崩潰,當然,在真實的設備上,是可以等待的,有的并不會造成崩潰,比如經在小米上測試50秒,程序并沒有崩潰,而是等待下去,直到程序正常。當這樣會造成不好的用戶體驗。所以在以后開發過程中,要充分考慮到這些容易出錯的情況。
③使用onLowMemory()回調方法監視低內存
該方法的原型為:
public void onLowMemory(){}
當整個系統在低內存運行時,將調用該方法。
好的應用程序會實現該方法來釋放任何緩存或者其他不需要的資源。系統從該方法返回之后,將執行一個垃圾回收操作。
④使用registerActivityLifecycleCallbacks()注冊可以監視Activity生命周期的接口
registerActivityLifecycleCallbacks()方法的原型為:
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback){}
在該方法中,參數callbacks表示Activity生命周期的接口。
從Android4.0以后,Android SDK為應用程序提供了一套完整的接口以便監視與本Application相關的Activity的生命周期(創建,啟動以及暫停等),它的名字叫做ActivityLifecycleCallbacks。只要在Application中通過registerActivityLifecycleCallbacks()方法將接口注冊上,它就會通過ActivityLifecycleCallbacks提供應用程序中相關的Activity生命周期信息。下表列出了這些接口以及用途。
特別提醒:從接口定義中,我們可以知道如下信息。
Ⅰ這些接口都是抽象的,因此當我們實現ActivityLifecycleCallbacks接口時,就必須實現這些方法,哪怕只是空實現。
Ⅱ這些接口的返回值都是void,這說明它們只用于通知,別無它用。
另外我們在必要時要調用unregisterActivityLifecycleCallbacks()方法來注銷掉原先注冊的接口以免造成不必要的資源浪費。
下面我們通過一個實例來說明配置發生變化的時候,系統如何通過onConfigurationChanged()回調接口來通知應用程序,具體的步驟如下所示。
㈠實現自己的Application子類(名叫ALCApplication)。我們將在應用程序創建(onCreate()方法中)時注冊自己的Activity生命周期接口,在程序終止(onTerMinate()方法中)時注銷這個接口。當完成這些工作以后,將得到如下所示的代碼:
public class ALCApplication extends Application { private final static String TAG="ALCApplication"; private ActivityLifecycleCallbacks mActivityLifecycleCallbacks=new ActivityLifecycleCallbacks() { @Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { Log.e(TAG,"onActivityCreated"); } @Override public void onActivityStarted(Activity activity) { Log.e(TAG,"onActivityStarted"); } @Override public void onActivityResumed(Activity activity) { Log.e(TAG,"onActivityResumed"); } @Override public void onActivityPaused(Activity activity) { Log.e(TAG,"onActivityPaused"); } @Override public void onActivityStopped(Activity activity) { Log.e(TAG,"onActivityStopped"); } @Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) { Log.e(TAG,"onActivitySaveInstanceState"); } @Override public void onActivityDestroyed(Activity activity) { Log.e(TAG,"onActivityDestroyed"); } }; @Override public void onCreate() { super.onCreate(); registerActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks); } @Override public void onTerminate() { super.onTerminate(); unregisterActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks); } }
㈡將ALCApplication配置到AndroidManifest.xml中,當配置完成時,最后的結果看起來與下圖類似:
這里我們通過接口監視Activity從啟動到推出的生命周期。
在這個實例中,我們在onTerminate()方法中做了注銷接口的工作。但值得注意的是,onTerminate()方法只會在虛擬機進程中被調用,永遠不會在真實的Android設備中被調用。
⑤使用registerComponentCallbacks()注冊一個可以用來艦艇Activity生命周期的接口
該方法原型為:
public void registerComponentCallbacks(ComponentCallbacks callback){}
其中參數callback是ComponentCallbacks 接口的一個實現。當Activity的生命周期發生變化時,會通過這個接口通知應用程序。對于所有應用程序來,它是通用的回調API集合的接口。ComponentCallbacks中只包括兩個方法,它們分別是public abstract void onConfigurationChanged(Configuration newConfig)和public abstract void onLowMemory()。 這兩個方法的調用與Application中的同名回調方法的調用條件一樣的。
ComponentCallbacks()和registerComponentCallbacks()方法的用法與ActivityLifecycleCallbacks()和registerActivityLifecycleCallbacks()的用法是一樣的,這里就不單舉例說明了。
Android
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。