Android清单文件详解(三)----应用程序的根节点application
<application>節(jié)點(diǎn)是AndroidManifest.xml文件中必須持有的一個(gè)節(jié)點(diǎn),它包含在<manifest>節(jié)點(diǎn)下。通過<application>節(jié)點(diǎn)的相關(guān)屬性,我們可以聲明Android應(yīng)用程序的相關(guān)特性。這個(gè)節(jié)點(diǎn)包含所有應(yīng)用程序組件的節(jié)點(diǎn),包括Activity,服務(wù),廣播接收器和內(nèi)容提供者,并且包含了一些可能影響所有組件的屬性。這些屬性中的其中一些又會(huì)作為默認(rèn)值而被設(shè)置到應(yīng)用程序組件的相同屬性上,比如icon,label,permission,process,taskAffinity和allowTaskReparenting等,而其他的一些值則作為應(yīng)用程序的整體被設(shè)置,并且不能被應(yīng)用程序組件的屬性覆蓋,比如debuggable,enabled,description和allowClearUserData等。
?
?
1.<application>節(jié)點(diǎn)配置
?
一般來說,在生成Android應(yīng)用程序的時(shí)候,默認(rèn)的AndroidManifest.xml文件中就已經(jīng)包含了一些默認(rèn)的<application>節(jié)點(diǎn),其中包含應(yīng)用程序的基本屬性?,F(xiàn)在我們就來看看<application>節(jié)點(diǎn)信息的全集,代碼如下:
?
?
<application android:allowTaskReparenting=["true"|"false"]
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">
</application>
?
?
2.如何實(shí)現(xiàn)Application類
?
首先要介紹的是android:name屬性,它指的是Application類的子類,當(dāng)應(yīng)用程序進(jìn)程被啟動(dòng)的時(shí)候,由android:name屬性指定的類將會(huì)在所有應(yīng)用程序組件(activity,服務(wù),廣播接收器,內(nèi)容提供者)被實(shí)例化之前實(shí)例化。
?
一般情況下,應(yīng)用程序無需指定這個(gè)屬性,Android會(huì)實(shí)例化Android框架下的applicaiton類。
?
然而,在一些特殊的情況下,比如希望在應(yīng)用程序組件啟動(dòng)之前就完成一個(gè)初始化工作,或者在系統(tǒng)低內(nèi)存的時(shí)候做一些特別的處理,就要考慮實(shí)現(xiàn)自己的Application類的一個(gè)子類。
?
在Android系統(tǒng)提供的系統(tǒng)應(yīng)用中,就有一個(gè)實(shí)現(xiàn)了自己的Application實(shí)例,這個(gè)應(yīng)用程序就是Launcher。我們可以仿照它來實(shí)現(xiàn)一個(gè)自己的Application類,具體步驟如下。
?
①創(chuàng)建一個(gè)叫做ApplicationTest的項(xiàng)目,并且在默認(rèn)生成的MainActivity里的onCreate()方法中添加一行代碼來輸出一條日志。這樣就可以看到Application創(chuàng)建時(shí)間,具體代碼如下:
?
?
public class MainActivity extends Activity {private static final String TAG="MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.e(TAG,"MainActivity is created");} }?
?
?
②實(shí)現(xiàn)自己的MyApplication類,代碼如下:
?
?
public class MyApplication extends Application {private static final String TAG="MyApplication";@Overridepublic void onCreate() {super.onCreate();Log.e(TAG,"MyApplication is created");} }?
?
③將MyApplication添加到清單文件AndroidManifest.xml中<application>內(nèi)android:name中
?
?
從圖中可以看出來,Android先創(chuàng)建的MyApplication,最后才創(chuàng)建的MainActivity。
?
?
?
3.Application提供的函數(shù)及其用法
?
?
android.app.Application類提供了許多類似onCreate()的方法,它們會(huì)在不同的場(chǎng)景下被Android框架回調(diào)。與此同時(shí),Application類還提供了一些監(jiān)控的函數(shù),用于監(jiān)視本應(yīng)用中組件的生命周期。如下表所示:
?
?
| 方法名稱 ? ? ? ? ? ? ? ? ? ?? | ? ? ? ? ? ? ? ? ? ? ? ?? ?返回值 ? ? ? ? ? ? ? ? ? | 注解 |
| onConfigurationChanged(Configuration newConfig) | void? | 如果組件正在運(yùn)行時(shí)設(shè)備配置(包括語(yǔ)種,方向,網(wǎng)絡(luò)等)發(fā)生改變,則由系統(tǒng)調(diào)用此方法通知應(yīng)用程序 |
| onCreate() | void | 當(dāng)應(yīng)用程序正在啟動(dòng)時(shí),并且在創(chuàng)建任何其他應(yīng)用程序?qū)ο笾?#xff0c;調(diào)用此方法。由于花費(fèi)在此功能上的時(shí)間直接影響了啟動(dòng)一個(gè)進(jìn)程中首個(gè)Activity服務(wù)或者接收器的速度,所以盡可能快地執(zhí)行(例如使用緩慢的初始化狀態(tài))。如果你重寫了這個(gè)方法,需要確保調(diào)用super.onCreated() 需要注意的是,在實(shí)際應(yīng)用程序中,如果你的應(yīng)用程序中的某些組件指定了一個(gè)process屬性(進(jìn)程),并且此進(jìn)程并不存在,那么Application的onCreate()回調(diào)就會(huì)被調(diào)用,換句話說,此方法可能會(huì)被多次調(diào)用 |
| onLowMemory() | void | 當(dāng)整個(gè)系統(tǒng)正在低內(nèi)存運(yùn)行時(shí),并且希望應(yīng)用程序縮減使用內(nèi)存的時(shí)候,系統(tǒng)調(diào)用此方法通知應(yīng)用程序。但調(diào)用此方法的準(zhǔn)確點(diǎn)沒有定義時(shí),通常它將在所有后臺(tái)進(jìn)程已經(jīng)終止的時(shí)間附近發(fā)生。 應(yīng)用程序可執(zhí)行此方法來釋放任何緩沖或其擁有的不必要的資源。系統(tǒng)在從此方法中返回后運(yùn)行垃圾回收操作。 |
| onTerminate() | void | 此方法在仿真進(jìn)程環(huán)境中使用,不在生產(chǎn)Android設(shè)備上調(diào)用,在生產(chǎn)Android設(shè)備上,可以通過簡(jiǎn)單地終止進(jìn)程來移除進(jìn)程。進(jìn)行移除工作時(shí),則不執(zhí)行任何用戶代碼(包括此回調(diào)) |
| onTrimMemory() | void | 回收內(nèi)存的時(shí)候調(diào)用。例如,當(dāng)它進(jìn)入后臺(tái)并且沒有足夠內(nèi)存保持許多后臺(tái)進(jìn)程運(yùn)行時(shí)。 |
| 監(jiān)控回調(diào)接口 registerComponentCallbacks unregisterComponentCallbacks | void void | 在應(yīng)用程序中注冊(cè)一個(gè)ComponentCallbacks接口。在Activity生命周期發(fā)生改變之前,通過此接口的各個(gè)方法通知應(yīng)用程序。使用這個(gè)接口,我們可以在Activity生命周期發(fā)生改變之前做一些必要的處理 需要大家注意的是,必須確保在未來恰當(dāng)?shù)臅r(shí)候使用unregisterComponentCallbacks(ComponentCallbacks)移除ComponentCallbacks對(duì)象,它是我們之前用registerComponentCallbacks(ComponentCallbacks)注冊(cè)的。 |
?
?
接下來,我們通過一些實(shí)例來說明如何使用這些方法和接口
?
①使用onConfigurationChanged()方法監(jiān)聽系統(tǒng)配置更新
?
onConfigurationChanged()方法的函數(shù)原型如下:
?
public void?onConfigurationChanged(Configuration newConfig){}其中newConfig參數(shù)表示新的設(shè)備配置
?
onConfigurationChanged()方法是一個(gè)回調(diào)接口,在設(shè)備配置發(fā)生變化時(shí)由Android系統(tǒng)調(diào)用。與此同時(shí),Android系統(tǒng)會(huì)通過參數(shù)(newConfig)傳給應(yīng)用程序,由應(yīng)用程序處理這個(gè)變化。注意,不同于Activity,其他組件在一個(gè)配置改變時(shí)從不重新啟動(dòng),它們孫弱自己處理改變的結(jié)果。這里所述的“配置”如下表所示:
?
?
| 配置項(xiàng) | 注解 |
| fontScale | 表示當(dāng)前的系統(tǒng)的字體縮放比例,它是基于像素密度縮放的。 注意,在使用用戶模式編譯出來的系統(tǒng)固件中,不包含修改此項(xiàng)配置的界面,只能通過編程的方法去改變。 數(shù)據(jù)類型:浮點(diǎn)型 |
| hardKeyBoardHidden | 指示硬鍵盤是否被隱藏起來,此配置項(xiàng)有3個(gè)取值,具體如下所示。 0.HARDKEYBOARDHIDDEN_UNDEFINED(Android無法識(shí)別的鍵盤狀態(tài)) 1.HARDKEYBOARDHIDDEN_NO(硬鍵盤可用) 2.HARDKEYBOARDHIDDEN_YES(硬鍵盤被隱藏) 數(shù)據(jù)類型:整型 |
| keyboard | 指示添加到設(shè)備上的是哪個(gè)種類的鍵盤,此配置項(xiàng)有以下4個(gè)取值 0.KEYBOARD_UNDEFINED(Android無法識(shí)別的鍵盤) 1.KEYBOARD_NOKEYS(無按鍵鍵盤) 2.KEYBOARD_QWERTY(打字機(jī)鍵盤) 3.KEYBOARD_12KEY(12鍵鍵盤) 數(shù)據(jù)類型:整型 |
| keyboardHidden | 指示當(dāng)前是否有鍵盤可用。如果在有硬鍵盤的Android設(shè)備中,硬鍵盤被收起,而仍有軟鍵盤,則認(rèn)為鍵盤是可用的。這個(gè)字段有如下3個(gè)取值。 0.KEYBOARDHIDDEN_UNDEFINED(Android無法識(shí)別的鍵盤狀態(tài)) 1.KEYBOARDHIDDEN_NO(仍有軟鍵盤可見) 2.KEYBOARDHIDDEN_YES(所有的軟鍵盤都被隱藏)。 數(shù)據(jù)類型:整型 |
| locale | 定義了設(shè)備的語(yǔ)言環(huán)境。它包含了國(guó)家以及語(yǔ)言信息,這些信息被包含在一個(gè)java.util.Locale類型的對(duì)象中 |
| mcc | IMSI的移動(dòng)國(guó)家碼,如果是0,表示未定義。 注意:IMSI是指國(guó)際移動(dòng)用戶識(shí)別碼,它存儲(chǔ)在我們的SIM卡中,其總長(zhǎng)度不超過15位。 數(shù)據(jù)類型:整型 |
| mnc | IMSI的移動(dòng)網(wǎng)絡(luò)號(hào),如果是0表示未定義 數(shù)據(jù)類型:整型 |
| navigation | 指示當(dāng)前設(shè)備可用的導(dǎo)航方式,它有如下5個(gè)取值。 0.NAVIGATION_UNDEFINED(未定義的導(dǎo)航方式) 1.NAVIGATION_NONAV(無導(dǎo)航) 2.NAVIGATION_DPAD(面板導(dǎo)航方式) 3.NAVIGATION_TRACKBALL(軌跡球?qū)Ш?#xff09; 4.NAVIGATION_WHEEL(滾輪方式導(dǎo)航) 數(shù)據(jù)類型:整型 |
| navigationHidden | 用于指示導(dǎo)航是否可用,有如下取值。 0.NAVIGATIONHIDDEN_UNDEFINED 1.NAVIGATIONHIDDEN_NO 2.NAVIGATIONHIDDEN_YES 數(shù)據(jù)類型:整型 |
| orientation | 指示屏幕方向的標(biāo)志,有如下4個(gè)取值。 0.ORIENTATION_UNDEFINED(未定義的方法) 1.ORIENTATION_PORTRAIT(豎屏方向,屏幕寬度小于高度) 2.ORIENTATION_LANDSCAPE(橫屏方向,屏幕寬度大于高度) 3.ORIENTATION_SQUARE(正方形屏幕,認(rèn)為屏幕寬度等于高度) 注意:在窗口管理服務(wù)(WindowManagerService)中計(jì)算新配置時(shí),orientation的默認(rèn)配置是ORIENTATION_SQUARE 數(shù)據(jù)類型:整型 |
| screenHeightDp | 屏幕可用部分的高度 |
| screenLayout | 指示屏幕的整體屬性,它包括兩個(gè)部分。 ⒈SCREENAYOUT_SIZE_MASK:標(biāo)志屏幕大小的屬性(比如大屏幕,小屏幕等),它有以下5個(gè)取值。 SCREENAYOUT_SIZE_UNDEFINED:未定義(值:0) SCREENAYOUT_SIZE_SMALL:小屏幕(值:1,屏幕分辨率至少為320*426)。 SCREENAYOUT_SIZE_NORMAL:普通屏幕(值:2,屏幕分辨率至少為320*470) SCREENAYOUT_SIZE_LARGE:大屏幕(值:3,屏幕分辨率至少為480*640) SCREENAYOUT_SIZE_XLARGE:加大屏幕(值:4,屏幕分辨率至少為720*960) ⒉SCREENAYOUT_LONG_MASK:指示屏幕是否比通常情況上更高或者更寬,它有如下3個(gè)取值。 SCREENAYOUT_LONG_UNDEFINED:未定義(十六進(jìn)制值為0) SCREENAYOUT_LONG_YES:是(十六進(jìn)制值為20) SCREENAYOUT_LONG_NO:否(十六進(jìn)制值為10) |
| screenWidthDp | 屏幕可用部分的寬度 |
| smallestScreenWidthDp | 在正常操作中,應(yīng)用程序?qū)?huì)看到最小的屏幕尺寸。這是在豎屏和橫屏中screenWidthDp和ScreenHeightDp的最小值。 |
| touchscreen | 設(shè)備上觸摸屏的種類,它支持如下取值。 0.TOUCHSCREEN_UNDEFINED(未定義模式) 1.TOUCHSCREEN_NOTOUCH(無觸屏模式) 2.TOUCHSCREEN_STYLUS(手寫筆模式) 3.TOUCHSCREEN_FINGER(手指觸屏模式) |
| uiMode | UI模式的位掩碼,目前有兩個(gè)字段。 ⒈UI_MODE_TYPE_MASK:定義了設(shè)備的整個(gè)UI模式,它支持如下取值。 UI_MODE_TYPE_UNDEFINED:未知模式 UI_MODE_TYPE_NORMAL:通常模式 UI_MODE_TYPE_DESK:帶底座模式‘ UI_MODE_TYPE_CAR:車載模式 ⒉UI_MODE_NIGHT_MASK:定義了屏幕是否在一個(gè)特殊模式中。它支持如下取值。 UI_MODE_NIGHT_UNDEFINED:未定義模式 UI_MODE_NIGHT_NO:非夜晚模式 UI_MODE_NIGHT_YES:夜晚模式 |
?
?
下面我們通過一個(gè)實(shí)例來說明當(dāng)設(shè)備配置發(fā)生變化的時(shí)候,系統(tǒng)如何通過onConfigurationChanged回調(diào)接口來通知應(yīng)用程序的。
?
㈠為前面的應(yīng)用程序添加一個(gè)名叫ConfigApplication的Application的子類,并實(shí)現(xiàn)onCreate()方法及onConfigurationChanged()方法。在onCreate()方法中,我們會(huì)獲取應(yīng)用程序在創(chuàng)建之初所擁有的配置信息。而在onConfigurationChanged()方法中,則可以添加一些代碼以便用日志的方式來實(shí)時(shí)體現(xiàn)配置更新。相關(guān)代碼如下:
?
?
public class ConfigApplication extends Application {private static final String TAG="ConfigApplication";private Configuration mConfiguration;@Overridepublic void onCreate() {super.onCreate();this.mConfiguration=getResources().getConfiguration();//獲取配置信息Log.e(TAG,"onCreate::infomation:orientation="+this.mConfiguration.orientation);}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);//打印更新后的配置信息Log.e(TAG,"onConfigurationChanged:infomation:orientation="+newConfig.orientation);} }?
?
㈡按前文所述,將ConfigApplication配置到AndroidManifest.xml文件中。
?
㈢設(shè)備運(yùn)行應(yīng)用程序,就可以看到如下的日志信息了。
?
?
對(duì)于日志,說明如下:
?
日志信息的第一行是初始狀態(tài)下的方向配置,通過上圖我們知道最初的方向值是1。而根據(jù)前面的表,可知當(dāng)前是豎屏方向。
?
日志信息的第五行是切換橫屏后,Android系統(tǒng)回調(diào)了我們實(shí)現(xiàn)的onConfigurationChanged()方法,這時(shí)系統(tǒng)配置已經(jīng)發(fā)生了改變,因此這里的日志打印了當(dāng)前的屏幕方向是2,也是就橫屏。
?
建議:由于基類onConfigurationChanged()方法中實(shí)現(xiàn)了對(duì)一些回調(diào)接口的調(diào)用,所以如果我們重寫了這個(gè)方法,那么為了維持原Application類的行為,建議在重寫的方法入口調(diào)用super.onConfigurationChanged(newConfig)。
?
②使用onCreate()完成應(yīng)用程序初始化
?
onCreate()方法的原型為:
?
public void onCreate(){}
?
?
如前面的表所示,onCreate()方法是一個(gè)回調(diào)接口。Android系統(tǒng)會(huì)在應(yīng)用程序啟動(dòng)的時(shí)候,在任何應(yīng)用程序組件(Activity,服務(wù),廣播接收器,內(nèi)容提供者)被創(chuàng)建之前調(diào)用這個(gè)接口。
?
需要注意的是,這個(gè)方法的執(zhí)行效率會(huì)直接影響到啟動(dòng)Activity,服務(wù),廣播接收器,或者內(nèi)容提供者的性能,因此該方法應(yīng)盡可能快地完成。
?
最后,如果實(shí)現(xiàn)了這個(gè)回調(diào)接口,請(qǐng)前晚不要忘記調(diào)用super.onCreate(),否則應(yīng)用程序會(huì)報(bào)錯(cuò)。
?
前面我們實(shí)現(xiàn)了Appplication類的子類------Configuration,并且也已經(jīng)實(shí)現(xiàn)了自身的onCreate()方法。這里來做個(gè)小實(shí)驗(yàn),讓大家更清楚這些知識(shí)。
?
現(xiàn)在,在源代碼的onCreate()方法中加入一個(gè)大約20秒的等待,以此來模擬在onCreate()方法中做了過于繁重的工作而導(dǎo)致該方法長(zhǎng)時(shí)間無法完成的情況,修改后的代碼如下:
?
?
public class ConfigApplication extends Application {private static final String TAG="ConfigApplication";private Configuration mConfiguration;@Overridepublic void onCreate() {super.onCreate();this.mConfiguration=getResources().getConfiguration();//獲取配置信息Log.e(TAG,"onCreate::infomation:orientation="+this.mConfiguration.orientation);SystemClock.sleep(20000);//沉睡20秒}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);//打印更新后的配置信息Log.e(TAG,"onConfigurationChanged:infomation:orientation="+newConfig.orientation);} }?
?
此時(shí)運(yùn)行程序,程序就會(huì)崩潰,當(dāng)然,在真實(shí)的設(shè)備上,是可以等待的,有的并不會(huì)造成崩潰,比如經(jīng)在小米上測(cè)試50秒,程序并沒有崩潰,而是等待下去,直到程序正常。當(dāng)這樣會(huì)造成不好的用戶體驗(yàn)。所以在以后開發(fā)過程中,要充分考慮到這些容易出錯(cuò)的情況。
?
③使用onLowMemory()回調(diào)方法監(jiān)視低內(nèi)存
?
該方法的原型為:
?
public void onLowMemory(){}
?
當(dāng)整個(gè)系統(tǒng)在低內(nèi)存運(yùn)行時(shí),將調(diào)用該方法。
?
?
好的應(yīng)用程序會(huì)實(shí)現(xiàn)該方法來釋放任何緩存或者其他不需要的資源。系統(tǒng)從該方法返回之后,將執(zhí)行一個(gè)垃圾回收操作。
?
④使用registerActivityLifecycleCallbacks()注冊(cè)可以監(jiān)視Activity生命周期的接口
?
registerActivityLifecycleCallbacks()方法的原型為:
?
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback){}
?
在該方法中,參數(shù)callbacks表示Activity生命周期的接口。
?
從Android4.0以后,Android SDK為應(yīng)用程序提供了一套完整的接口以便監(jiān)視與本Application相關(guān)的Activity的生命周期(創(chuàng)建,啟動(dòng)以及暫停等),它的名字叫做ActivityLifecycleCallbacks。只要在Application中通過registerActivityLifecycleCallbacks()方法將接口注冊(cè)上,它就會(huì)通過ActivityLifecycleCallbacks提供應(yīng)用程序中相關(guān)的Activity生命周期信息。下表列出了這些接口以及用途。
?
?
?
| 方法原型 | 參數(shù)說明 | 用途 |
| abstract void onActivityCreated(Activity activity,Bundle savedInstanceState) | activity:創(chuàng)建的Activity實(shí)例 savedInstanceState:創(chuàng)建該Activity時(shí)所帶的信息(一個(gè)Bundle實(shí)例) | 在應(yīng)用程序創(chuàng)建Activity之前調(diào)用,用于通知接口實(shí)現(xiàn)者Activity將要被創(chuàng)建。 |
| abstract void onActivityDestroyed(Activity activity) | activity:銷毀的Activity實(shí)例 | 在應(yīng)用程序銷毀Activity之前調(diào)用,用于通知接口實(shí)現(xiàn)者Activity將要被銷毀。 |
| abstract void onActivityPaused(Activity activity) | activity:暫停的Activity實(shí)例 | 在應(yīng)用程序暫停Activity之前調(diào)用,用于通知接口實(shí)現(xiàn)者Activity將要被暫停。 |
| abstract void onActivityResumed(Activity activity) | activity:恢復(fù)的Activity實(shí)例 | 在應(yīng)用程序正在恢復(fù)Activity之前調(diào)用,用于通知接口實(shí)現(xiàn)者Activity將要被恢復(fù)。 |
| abstract void?onActivitySaveInstanceState(Activity activity,Bundle outState) | activity:正在執(zhí)行狀態(tài)保存的的Activity實(shí)例 outState:需要保存的Activity狀態(tài) | 指示當(dāng)前Activity正在保存自己的狀態(tài),這些狀態(tài)包含在outState中。 |
| abstract void?onActivityStarted(Activity activity) | activity:啟動(dòng)的Activity實(shí)例 | 在應(yīng)用程序正在啟動(dòng)Activity之前調(diào)用,用于通知接口實(shí)現(xiàn)者Activity將要被啟動(dòng)。 |
| abstract void?onActivityStopped(Activity activity) | activity:停止的Activity實(shí)例 | 在應(yīng)用程序正在停止Activity之前調(diào)用,用于通知接口實(shí)現(xiàn)者Activity將要被停止。 |
?
?
特別提醒:從接口定義中,我們可以知道如下信息。
?
?
Ⅰ這些接口都是抽象的,因此當(dāng)我們實(shí)現(xiàn)ActivityLifecycleCallbacks接口時(shí),就必須實(shí)現(xiàn)這些方法,哪怕只是空實(shí)現(xiàn)。
?
Ⅱ這些接口的返回值都是void,這說明它們只用于通知,別無它用。
?
?
另外我們?cè)诒匾獣r(shí)要調(diào)用unregisterActivityLifecycleCallbacks()方法來注銷掉原先注冊(cè)的接口以免造成不必要的資源浪費(fèi)。
?
下面我們通過一個(gè)實(shí)例來說明配置發(fā)生變化的時(shí)候,系統(tǒng)如何通過onConfigurationChanged()回調(diào)接口來通知應(yīng)用程序,具體的步驟如下所示。
?
㈠實(shí)現(xiàn)自己的Application子類(名叫ALCApplication)。我們將在應(yīng)用程序創(chuàng)建(onCreate()方法中)時(shí)注冊(cè)自己的Activity生命周期接口,在程序終止(onTerMinate()方法中)時(shí)注銷這個(gè)接口。當(dāng)完成這些工作以后,將得到如下所示的代碼:
?
?
public class ALCApplication extends Application {private final static String TAG="ALCApplication";private ActivityLifecycleCallbacks mActivityLifecycleCallbacks=new ActivityLifecycleCallbacks() {@Overridepublic void onActivityCreated(Activity activity, Bundle savedInstanceState) {Log.e(TAG,"onActivityCreated");}@Overridepublic void onActivityStarted(Activity activity) {Log.e(TAG,"onActivityStarted");}@Overridepublic void onActivityResumed(Activity activity) {Log.e(TAG,"onActivityResumed");}@Overridepublic void onActivityPaused(Activity activity) {Log.e(TAG,"onActivityPaused");}@Overridepublic void onActivityStopped(Activity activity) {Log.e(TAG,"onActivityStopped");}@Overridepublic void onActivitySaveInstanceState(Activity activity, Bundle outState) {Log.e(TAG,"onActivitySaveInstanceState");}@Overridepublic void onActivityDestroyed(Activity activity) {Log.e(TAG,"onActivityDestroyed");}};@Overridepublic void onCreate() {super.onCreate();registerActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks);}@Overridepublic void onTerminate() {super.onTerminate();unregisterActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks);} }?
?
?
㈡將ALCApplication配置到AndroidManifest.xml中,當(dāng)配置完成時(shí),最后的結(jié)果看起來與下圖類似:
?
?
?
?
這里我們通過接口監(jiān)視Activity從啟動(dòng)到推出的生命周期。
?
在這個(gè)實(shí)例中,我們?cè)趏nTerminate()方法中做了注銷接口的工作。但值得注意的是,onTerminate()方法只會(huì)在虛擬機(jī)進(jìn)程中被調(diào)用,永遠(yuǎn)不會(huì)在真實(shí)的Android設(shè)備中被調(diào)用。
?
⑤使用registerComponentCallbacks()注冊(cè)一個(gè)可以用來艦艇Activity生命周期的接口
?
該方法原型為:
?
public void registerComponentCallbacks(ComponentCallbacks callback){}
?
其中參數(shù)callback是ComponentCallbacks 接口的一個(gè)實(shí)現(xiàn)。當(dāng)Activity的生命周期發(fā)生變化時(shí),會(huì)通過這個(gè)接口通知應(yīng)用程序。對(duì)于所有應(yīng)用程序來,它是通用的回調(diào)API集合的接口。ComponentCallbacks中只包括兩個(gè)方法,它們分別是public abstract void onConfigurationChanged(Configuration newConfig)和public abstract void onLowMemory()。 這兩個(gè)方法的調(diào)用與Application中的同名回調(diào)方法的調(diào)用條件一樣的。
?
ComponentCallbacks()和registerComponentCallbacks()方法的用法與ActivityLifecycleCallbacks()和registerActivityLifecycleCallbacks()的用法是一樣的,這里就不單舉例說明了。
?
轉(zhuǎn)載于:https://www.cnblogs.com/liyuanjinglyj/p/application.html
總結(jié)
以上是生活随笔為你收集整理的Android清单文件详解(三)----应用程序的根节点application的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iphone开发基础:loadView/
- 下一篇: OS开发UI篇—popoverContr