Application全域性應用

Tim的小站發表於2020-12-07

Application是維護應用全域性狀態的基類,Android系統會在啟動應用程式時建立一個對應的Application物件。所以當我們需要建立全域性變數的時候,不需要再像Java那樣需要建立public許可權的static變數,而直接在Application中去實現。其他元件只需要呼叫Context的getApplicationContext或者getApplication(在Activity中)來獲得一個Application物件,再做出相應的處理。

自定義Application

我們可以通過建立一個子類,並在AndroidManifest.xml的<application>標籤中將該子類的標準名稱指定為"android:name" 屬性來設定為自己的實現類。

public class MyApplication extends Application {
    // ...
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.tim.custom_application">
    <application
        android:name=".MyApplication"
        ...
        android:theme="@style/AppTheme">
        ...
    </application>
</manifest>

MainActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.i(TAG, "onCreate: " + getApplication());
}

列印出來的確實自定義的Application類物件:

MainActivity: onCreate: cn.tim.custom_application.MyApplication@9e7a3660

Application物件生命週期

Application物件誕生於其它任何元件物件之前,並且一直存活,直到應用程式結束。Application物件由Android系統管理,它的回撥函式都執行於UI執行緒。

public class MyApplication extends Application {
    private static final String TAG = "MyApplication";

    // Application物件被建立的時候會呼叫
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i(TAG, "onCreate: " + this);
        Log.i(TAG, "onCreate: " + Thread.currentThread());
    }

    // 系統配置變更,如橫屏變成豎屏、系統語言更改
    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.i(TAG, "onConfigurationChanged: " + newConfig );
    }

    // 系統記憶體吃緊的時候被呼叫
    @Override
    public void onLowMemory() {
        super.onLowMemory();
        Log.i(TAG, "onLowMemory: ");
    }
}

Application物件的作用

Application物件全域性可訪問,且全程陪同應用程式。所以特別適合完成以下任務:初始化全應用所需的服務、共享全域性狀態、監聽配置資訊改變、監聽Activity生命週期

初始化全應用所需的服務:在 Application 物件被建立時會呼叫 onCreate()方法,此時用來初始化全應用所需的服務是個不錯的選擇,但是最好執行耗時操作,否則會拖慢應用程式啟動速度。

共享全域性狀態:另外使用Application物件實現資料共享、資料快取也是一個不錯的選擇。Application物件可以獲取應用程式當前的記憶體使用情況,及時釋放資源,從而避免被系統殺死。

監聽配置資訊改變:如螢幕旋轉,系統語言切換等(下面是手機開啟橫屏的示例)。

監聽Activity生命週期:監聽應用程式內所有Activity的生命週期。

Application物件 VS 靜態單例

Application物件與靜態單例都可以實現應用全域性狀態的共享,以共享Otto的Bus物件為例:

implementation group: 'com.squareup', name: 'otto', version: '1.3.8'

這是使用Application物件進行全域性共享的示例:

MyApplication.java

public class MyApplication extends Application {
    private Bus bus;

    public Bus getBus() {
        return bus;
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
        bus = new Bus();
    }
    
    ...
}

MainActivity.java

@Override
protected void onResume() {
    super.onResume();
    MyApplication application = (MyApplication) getApplication();
    Bus bus = application.getBus();
    bus.register(this);
}

@Override
protected void onPause() {
    super.onPause();
    MyApplication application = (MyApplication) getApplication();
    Bus bus = application.getBus();
    bus.unregister(this);
}

這是使用靜態單例進行全域性共享的示例:
BusProvider.java

public class BusProvider {
    private BusProvider(){}
    private static final Bus bus = new Bus();

    public static Bus getBus(){
        return bus;
    }
}

OtherActivity.java

@Override
protected void onResume() {
    super.onResume();
    BusProvider.getBus().register(this);
    Log.i(TAG, "onResume: bus = " + BusProvider.getBus());
}

@Override
protected void onPause() {
    super.onPause();
    BusProvider.getBus().unregister(this);
    Log.i(TAG, "onPause: bus = " + BusProvider.getBus());
}

1、靜態單例模組化程度更好
2、Application就是一個context,所以有訪問資源的能力
3、靜態單例可以接受context引數
4、Application物件能接收系統回撥,自動知悉系統環境變化
5、Application物件的生命週期由系統控制

原文地址:《Application全域性應用》

相關文章