Android---理解Application類

對Application類的理解(Android API6.0):

  • 每個APP都有一個Application實例:如果我們沒有繼承Application子類自定義它的話,APP會創建一個默認的實例。
  • Application實例擁有着與APP一樣長的生命週期:在APP開啓的時候首先就會實例化它,然後纔是入口的Activity或者Service等。
  • Application與APP“同生共死”,在一個APP的生命週期只實例化一次,所以它“天生”就是一個單例,不需要使用單例模式去實現它。
  • 而上面的官方Note裏面說到,通常是沒有必要實現Application的子類的,要用單例的話可以自己使用靜態單例類實現,要用它的Context的話用Context.getApplicationContext()就行了。然而,Application類的作用可不單單是實現一個全局的單例,還有其他的很多功能,下面一一介紹
可以看到Application extends ContextWrapper implements ComponentCallbacks2
Application是繼承自ContextWarpper的,而ContextWrapper繼承Context ,Context 繼承 Object

onCreate()方法

  在Application創建的時候調用,一般用於初始化一些東西,如全局的對象,環境的配置等。

onConfigurationChanged(Configuration newConfig)方法

  重寫此方法可以監聽APP一些配置信息的改變事件(如屏幕旋轉等),當配置信息改變的時候會調用這個方法。在Manifest文件下的Activity標籤(注意是Activity)裏配置Android:configChanges屬性相應的配置屬性,會使Activity在配置改變時候不會重啓,只會執行onConfigurationChanged()方法。如:android:configChanges="keyboardHidden|orientation|screenSize"屬性可以使Activity旋轉時不重啓。

onLowMemory()方法

  重寫此方法可以監聽Android系統整體內存較低時候的事件。按我的理解就是,當APP處於前臺時,但是所有後臺程序都被kill光了,但是還是內存不足時,系統就會調用這個方法告訴APP,兄弟輪到你了。我們可以在這個方法裏面釋放一些不重要的資源,來保證到時候內存足夠而讓APP進程不被系統殺掉,或者提醒用戶清一下垃圾,讓內存清一點空位出來,我的手機老是這樣提示我,不知道是不是這個方法惹的禍。

onTrimMemory(int level)方法

  這個方法是一個比較難理解的方法,Trim意思是修剪,按我的理解,用這個方法打個比方:   從前有個偉大的媽媽叫Android系統,她有一羣子女叫APP,她含辛茹苦地養着這羣熊孩子。當系統老媽發現她的工資(內存)不夠下個月的開銷的時候,就會回調這個方法,告訴她的APP子女,我現在工資不夠了,你們趕緊少吃少用點,不然我就要根據你們的重要性高低來一個一個地“清理門戶”了。   這裏有傳入一個int類型的參數level,它告訴APP們內存不足的嚴重性(越高越嚴重)。假如這時候系統內存不足,運行着前臺和後臺一共幾個APP,這些不同的APP會收到系統老媽不同的“勸告信息”:

  • TRIM_MEMORY_RUNNING_MODERATE:數值爲5,這個APP是系統老媽的“掌上明珠”(前臺APP),老媽讓APP注意一下:不要大手大腳(釋放不用的內存),我的工資(內存)不夠養你了,不過就算再不夠,只是把你其他不爭氣兄弟姐妹(殺掉後臺APP)清出家門,你注意一下吧。
  • TRIM_MEMORY_RUNNING_LOW:數值10,這個APP是系統老媽的“掌上明珠”(前臺APP),老媽語重心長地對APP說:孩子,我的工資(內存)實在不夠了,你能不能拿點壓歲錢出來幫補一下(釋放不用的內存),不行的話就要把你的很多兄弟姐妹(殺掉後臺APP)送走了。
  • TRIM_MEMORY_RUNNING_CRITICAL:數值15,這個APP是系統老媽的“掌上明珠”(前臺APP),老媽嚴重警告APP:臭小子,你的兄弟姐妹(殺掉後臺APP)都快走光了,你還不給我多省點錢(要求釋放內存),你還真的想把你的兄弟全趕走啊,當時候就剩你一個,說不定你都自身難保啦(執行onLowMemory()方法)。
  • TRIM_MEMORY_UI_HIDDEN:數值20,老媽告訴這個APP:你個熊孩子,闖了禍(用戶把APP從前臺切換到後臺),我要收回你的零用錢(UI資源)。
  • TRIM_MEMORY_BACKGROUND :數值40,這些APP是老媽收養的(後臺APP),老媽在吃完晚飯後留下了他,對他說:孩子啊,現在家裏經濟不好(內存不足),你就少花點吧,這個月的零用錢不發了吧(要求釋放資源),不然的話我們家可能養不下你和你後面的那幫兄弟姐妹了(殺掉後臺APP)。
  • TRIM_MEMORY_MODERATE :數值60,這些APP是老媽收養的(後臺APP),老媽偷偷地跟APP說:孩子啊,你們花費太多了,老媽的工資養不下你們了(內存不足),你們用少點吧(要求釋放內存),不然等我把你後面那幾個兄弟趕出去之後就輪到你了(已進入LRU緩存列表的中間位置,如果後面的APP進程資源都被回收的話,下一個就是輪到它了)。
  • TRIM_MEMORY_COMPLETE :數值80,這些APP是老媽充話費送的(後臺APP),老媽狠狠地對他說:臭小子,沒看到都快揭不開鍋了(內存不足)嗎?趕緊把你的私房錢拿出來(要求釋放資源),不然你們就準備滾出這個家門吧(已處於LRU緩存列表的後面位置,APP隨時都有被回收的風險)

    onTerminate()方法

  這個方法在程序結束的時候會調用。但是這個方法只用於Android仿真機測試的時候,在Android產品機是不會調用的。所以這個方法並沒什麼用。

registerActivityLifecycleCallbacks()和unregisterActivityLifecycleCallbacks()

  這兩個方法用於註冊或者註銷對APP內所有Activity的生命週期監聽,當APP內Activity的生命週期發生變化的時候就會調用ActivityLifecycleCallbacks裏面的方法:

registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                Log.d(TAG,"onActivityCreated: " + activity.getLocalClassName());
            }

            @Override
            public void onActivityStarted(Activity activity) {
                Log.d(TAG,"onActivityStarted: " + activity.getLocalClassName());
            }

            @Override
            public void onActivityResumed(Activity activity) {
                Log.d(TAG,"onActivityResumed: " + activity.getLocalClassName());
            }

            @Override
            public void onActivityPaused(Activity activity) {
                Log.d(TAG,"onActivityPaused: " + activity.getLocalClassName());
            }

            @Override
            public void onActivityStopped(Activity activity) {
                Log.d(TAG, "onActivityStopped: " + activity.getLocalClassName());
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                Log.d(TAG,"onActivityDestroyed: " + activity.getLocalClassName());
            }
        });

APP切到後臺再打開,log結果是:
 onActivityPaused: MainActivity
 onActivityStopped: MainActivity
 onActivityStarted: MainActivity
 onActivityResumed: MainActivity

registerComponentCallbacks()和unregisterComponentCallbacks()方法

  用於註冊和註銷ComponentCallbacks2回調接口,裏面的方法前面已經介紹過,看名字就知道:

registerComponentCallbacks(new ComponentCallbacks2() {
            @Override
            public void onTrimMemory(int level) {

            }

            @Override
            public void onConfigurationChanged(Configuration newConfig) {

            }

            @Override
            public void onLowMemory() {

            }
        });

Context類也有這兩個方法,但是Context類的方法只可以使用ComponentCallbacks,比Application少了一個onTrimMemory()回調。

registerOnProvideAssistDataListener()和unregisterOnProvideAssistDataListener()方法

  API18以上的方法,網上關於這兩個方法的介紹很少,幾乎沒有,在官網上的介紹是這樣的:

This is called when the user is requesting an assist, to build a full ACTION_ASSIST Intent with all of the context of the current application.

  好像是當用戶請求幫助的時候會調用這個方法,然後會啓動一個ACTION_ASSIST的Intent。什麼時候纔是用戶請求幫助呢?StackOverflow裏有的人說是長按Home鍵,外國的機子會跳出Google Now這個助手,至於國內的機子,我用我自己的華爲榮耀6P長按Home鍵是彈出語音助手,但是沒有回調這個方法。然後嘗試了一下用下面的代碼來發送一個ACTION_ASSIST來看看有什麼效果:

Intent intent = new Intent(ACTION_ASSIST);
        context.startActivity(intent);
結果打開了我手機上UC瀏覽器的語音搜索功能。。。
  最後還是搞不懂這個方法什麼時候會回調,如果有知道的請告知,謝謝!

Application類的使用

  要使用自定義的Application,首先就是要自己新建一個Application的子類,然後把它的名字寫在manifest文件裏面的application標籤裏的android:name屬性就行,如我的Application子類名字是BaseApplication,則:

android:name=".BaseApplication"

1.初始化資源

  由於Application類是在APP啓動的時候就啓動,啓動在所有Activity之前,所以可以使用它做資源的初始化操作,如圖片資源初始化,WebView的預加載,推送服務的註冊等等,注意不要執行耗時操作,會拖慢APP啓動速度。

2.數據全局共享

  • 可以設置一些全局的共享常量,如一些TAG,枚舉值等。
  • 可以設置一些全局使用的共享變量數據,如一個全局的Handler等等,但是要注意,這裏緩存的變量數據的作用週期只在APP的生命週期,如果APP因爲內存不足而結束的話,再開啓這些數據就會消失,所以這裏只能存儲一些不重要的數據來使數據全APP共享,想要儲存重要數據的話需要SharePreference、數據庫或者文件存儲等這些本地存儲。
  • 可以設置一些靜態方法來讓其他類調用,來使用Application裏面的全局變量,如實現APP一鍵退出功能時候會用到。


發佈了53 篇原創文章 · 獲贊 8 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章