独自のApplicationクラスを作る

以前のエントリで、Activityより前に実施したい処理、それも外部からActivityの生成に割り込みたい場合にどうすれば良いか、という事を過いた。

その後、他の事を調べていたために本件は放置していたのだが、未だに解決はしていない。
ただ、アプリケーションのエントリポイントという意味ではApplicationクラスは拡張することが出来、拡張したアプリケーションを共通のコンテナとして使うことはできる。

Application class - Android Developers

  • 手順
    • 1. Application (android.app.Application)クラスを拡張したクラスを用意する

ライフサイクルに関連したメソッド(onCreate, onTerminate, onConfigurationChanged, onLowMemory)をオーバイライドできる。また、独自のオブジェクトを公開するメソッドを追加するのも良いだろう。

package foo.bar;

public class HogeApplication extends Application {
    protected String globalData = "yaaaah";
    @Override
    public void onCreate() {
        //生成時
    }

    @Override
    public void onTerminate() {
        //終了時
    }

    public Object getGlobalData() {
        return this.globalData;
    }
}
    • 2. AndroidManifest.xmlを書き換える

application要素のname属性に、Applicationを拡張したクラスのFQN(fully qualified name)を記述する。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="foo.bar" android:versionCode="1" android:versionName="1.0">
    <application android:name="foo.bar.HogeApplication" android:icon="@drawable/icon" android:label="@string/app_name" >
        <activity android:name=".HogeActivity" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest> 

ここまで上手くいけば、実行時にはfoo.bar.HogeApplicationのインスタンスが生成されて、内部メソッドが呼ばれることを確認できるだろう。

    • 3. Activityから拡張したアプリケーションを取得する

元々ActivityにはApplicationを取得するメソッドがあるので、キャストすることで独自のアプリケーションの機能を使用できる。

  • Activityのコンテキスト中
    HogeApplication app = (HogeApplication)this.getApplication();
    Object data = app.getGlobalData();

これでアクティビティの生成に割り込むことができると思ったのだが、ApplicationとActivityはInstrumentationクラスから独自にインスタンスが生成され、Activityが生成されるタイミングをApplicationは知ることができないのだ。

さて、やはりActivityを拡張するしかないのか。