Activityのライフサイクルを別クラスに通知する


Anroid4.0(以降ICS)からApplicationクラスにActivityLifecycleCallbacksインターフェイスが追加されました。

このインターフェイスを実装することで、Activityのライフサイクルを通知することができます。

詳細は以下から。

ActivityLifecycleCallbacksインターフェイスは以下の流れで実装します。

  1. コールバックするActivityにActivityLifecycleCallbacksインターフェイスのセッターを実装する
  2. Activity側で通知したいライフサイクルに適切なコールバックメソッドを実行する
  3. コールバックを受け取りたいクラスにActivityLifecycleCallbacksインターフェイスを実装する

コールバックするActivityにActivityLifecycleCallbacksインターフェイスのセッターを実装する

ActivityLifecycleCallbacksインターフェイスの各通知用メソッドを実行するためには、ActivityLifecycleCallbacksインターフェイスのインスタンスを保持しておくことが必要です。

何かを通知するためのインターフェイスではセッターメソッドでインスタンスを取得することが一般的です。

以下のサンプルコードではActivityLifecycleCallbacksインターフェイス型のフィールドを宣言し、そのフィールドに対してセッターメソッドでActivityLifecycleCallbacksインターフェイスのインスタンスを代入しています。

ActivityLifecycleCallbacksSampleActivity.java

public class ActivityLifecycleCallbacksSampleActivity extends Activity {
    private ActivityLifecycleCallbacks mCallbacks;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
         CatchCallBackFragment fragment = new CatchCallBackFragment();  //このクラスは後で実装します
         this.setActivityLifecycleCallbacks(fragment);
         FragmentTransaction ft = getFragmentManager().beginTransaction();
         ft.add(R.id.fragment_space, fragment);
         ft.commit();
        
        if(mCallbacks != null && savedInstanceState != null){
            mCallbacks.onActivityCreated(this, savedInstanceState);
        }
    }
〜省略〜
    public void setActivityLifecycleCallbacks(
            ActivityLifecycleCallbacks callbacks) {
        this.mCallbacks = callbacks;
    }
}

10行目のCatchCallBackFragmentクラスはライフサイクルの通知を受け取るクラスで、後ほど実装します。

Activity側で通知したいライフサイクルに適切なコールバックメソッドを実行する

ActivityLifecycleCallbacksインターフェイスでは以下のライフサイクル通知用メソッドがあります。

[table “108” not found /]

以下のサンプルコードでは各ライフサイクルで通知用メソッドを実行しています。

ActivityLifecycleCallbacksSampleActivity.java

〜省略〜
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mCallbacks != null){
            mCallbacks.onActivityDestroyed(this);
        }
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        
        if(mCallbacks != null){
            mCallbacks.onActivityPaused(this);
        }
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        
        if(mCallbacks != null){
            mCallbacks.onActivityResumed(this);
        }
    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        
        if(mCallbacks != null){
            mCallbacks.onActivitySaveInstanceState(this, outState);
        }
    }
    
    @Override
    protected void onStart() {
        super.onStart();
        
        if(mCallbacks != null){
            mCallbacks.onActivityStarted(this);
        }
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        
        if(mCallbacks != null){
            mCallbacks.onActivityStopped(this);
        }
    }
〜省略〜

コールバックを受け取りたいクラスにActivityLifecycleCallbacksインターフェイスを実装する

最後にActivityLifecycleCallbacksインターフェイスの通知を受け取る側のクラスを作成します。

今回のサンプルではFragmentを継承したクラスでActivityからのコールバックを受け取っています。

以下のサンプルコードは通知を受け取るとToastを表示するシンプルな実装になっています。

実際には各通知メソッドにて各ライフサイクル時に実行したい処理を実装します。

CatchCallBackFragment.java

public class CatchCallBackFragment extends Fragment implements ActivityLifecycleCallbacks{
    
    public CatchCallBackFragment() {
    }

    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        Toast.makeText(getActivity(), "onActivityCreated", Toast.LENGTH_LONG).show();
    }

    public void onActivityDestroyed(Activity activity) {
        Toast.makeText(getActivity(), "onActivityDestroyed", Toast.LENGTH_LONG).show();
    }

    public void onActivityPaused(Activity activity) {
        Toast.makeText(getActivity(), "onActivityPaused", Toast.LENGTH_LONG).show();
    }

    public void onActivityResumed(Activity activity) {
        Toast.makeText(getActivity(), "onActivityResumed", Toast.LENGTH_LONG).show();
    }

    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        Toast.makeText(getActivity(), "onActivitySaveInstanceState", Toast.LENGTH_LONG).show();
    }

    public void onActivityStarted(Activity activity) {
        Toast.makeText(getActivity(), "onActivityStarted", Toast.LENGTH_LONG).show();
    }

    public void onActivityStopped(Activity activity) {
        Toast.makeText(getActivity(), "onActivityStopped", Toast.LENGTH_LONG).show();
    }
}

タブレットアプリ市場では大きな画面を活かした大規模アプリの開発がこれから多くなってくると予想されます。

OSが提供する基本フレームワークレベルでインターフェイスが統一できることは大規模アプリ開発にて大きなアドバンテージになるでしょう。

関連する記事: