2012-05-15 64 views
23

私は控えめに言って、しかし、この問題に関するドキュメントが不足している、自動的にActivityLifecycleCallbacksを使ってAndroidのライフサイクルイベントをキャプチャし、ログに記録しようとしています:ActivityLifecycleCallbacksを使用してAndroidライフサイクルイベントを自動的に記録しますか?

public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback) 

私はActivityクラスまたはオーバーライドを拡張する必要がありますする必要はありません既存のライフサイクルメソッド(onCreate、onResumeなど)...私は、これらのイベントをリスンしてそれに応じて別のクラスを取得することを検討しています。

誰でもこれを経験したことがありますか、またはこれがどのように機能するかについての良い文書やチュートリアルへのリンクがありますか?具体的には、ActivityLifecycleCallbacksの登録方法とその処理方法を教えてください。

+1

UPDATEを働くApplicationクラスに次の行を追加します。標準APIは現在約長くなっています@ ClarkXPのロールオーダーは大部分のアプリにとって過度のものです。代わりに@ Jeroenの答えを見てください。あなたのクラスが 'onCreate'または' init'を持っているか、または 'getCreate'()メソッドが呼び出されたときに' getApplication().ActivityLifecycleCallbacks(this)インスタンスがアクティブになったときに実行される同様のメソッドでは、コンストラクタではなく、その行を配置します(クラスは完全に準備が整うまでコールバックを受信したくないため)。 – ToolmakerSteve

答えて

29

Application.ActivityLifecycleCallbacksの独自の実装を行いました。 SherlockActivityを使用していますが、通常のアクティビティクラスでは動作する可能性があります。活動のライフサイクルを追跡するために

まず、私はすべてのメソッドを持つインターフェイスを作成しています:私は、

public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{ 

    @Override 
    public void onCreate() { 
     super.onCreate();   
    } 

    @Override 
    public void onActivityStopped(Activity activity) { 
     Log.i("Tracking Activity Stopped", activity.getLocalClassName()); 

    } 

    @Override 
    public void onActivityStarted(Activity activity) { 
     Log.i("Tracking Activity Started", activity.getLocalClassName()); 

    } 

    @Override 
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 
     Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityResumed(Activity activity) { 
     Log.i("Tracking Activity Resumed", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityPaused(Activity activity) { 
     Log.i("Tracking Activity Paused", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityDestroyed(Activity activity) { 
     Log.i("Tracking Activity Destroyed", activity.getLocalClassName()); 
    } 

    @Override 
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 
     Log.i("Tracking Activity Created", activity.getLocalClassName()); 
    } 
} 

サード:

public interface ActivityLifecycleCallbacks{ 
    public void onActivityStopped(Activity activity); 
    public void onActivityStarted(Activity activity); 
    public void onActivitySaveInstanceState(Activity activity, Bundle outState); 
    public void onActivityResumed(Activity activity); 
    public void onActivityPaused(Activity activity); 
    public void onActivityDestroyed(Activity activity); 
    public void onActivityCreated(Activity activity, Bundle savedInstanceState); 
} 

第二に、私は自分のアプリケーションのクラスで、このインタフェースを実装しましたSherlockActivityから継承するクラスを作成しています:

public class MySherlockActivity extends SherlockActivity { 

    protected MyApplication nMyApplication; 

    protected void onCreate(Bundle savedInstanceState) { 
     // TODO Auto-generated method stub 
     super.onCreate(savedInstanceState); 
     nMyApplication = (MyApplication) getApplication(); 
     nMyApplication.onActivityCreated(this, savedInstanceState); 
    } 

    protected void onResume() { 
     // TODO Auto-generated method stub 
     nMyApplication.onActivityResumed(this); 
     super.onResume(); 

    } 

    @Override 
    protected void onPause() { 
     // TODO Auto-generated method stub 
     nMyApplication.onActivityPaused(this); 
     super.onPause(); 
    } 

    @Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     nMyApplication.onActivityDestroyed(this); 
     super.onDestroy(); 
    } 

    @Override 
    protected void onStart() { 
     nMyApplication.onActivityStarted(this); 
     super.onStart(); 
    } 

    @Override 
    protected void onStop() { 
     nMyApplication.onActivityStopped(this); 
     super.onStop(); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     nMyApplication.onActivitySaveInstanceState(this, outState); 
     super.onSaveInstanceState(outState); 
    } 
} 

第4、すべてのクラスtha tはSherlockActivityから延びている、私はMySherlockActivityで交換:

public class MainActivity extends MySherlockActivity{ 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
    } 

} 

さて、logcatにあなたはMyApplicationをで行われたインタフェースの実装でプログラムのログが表示されます。

UPDATE

この実装は、APIレベル9(ジンジャーブレッド)、APIレベル12(ハニカム)とAPIレベル17(ジェリービーン)からテストされ、正常に動作しました。 Androidの古いバージョンで動作する可能性があります。

+2

完全性を確認するには、インターフェイスにonActivityRestart()を追加し、適切なメソッドをMyApplicationおよびMySherlockActivityに追加することを検討してください。このメソッドはAndroidのActivityLifecycleCallbacksの一部ではなく、アクティビティのライフサイクルの一部であることがわかりました。 –

+1

古いデバイスに便利です。注:あなた(誰でも)がApplication.ActivityLifecycleCallbacksを使用しようとしている場合は、最近の十分なAPIを想定しており、カスタムインターフェイスとアクティビティ拡張を省略できます。最初のコードセクションを実行してください。このセクションでは、インターフェイスを実装するためにクラス(この場合はApplication)を拡張する方法を示しますが、 'Application.ActivityLifecycleCallbacks'を実装します。そして(2) 'getApplication()。registerActivityLifecycleCallbacks(this);'あなたのコールバッククラスのコンストラクタまたはonCreate。 – ToolmakerSteve

39

私は身をもって経験を持っていないが、APIから判断すると、あなただけのApplication.ActivityLifecycleCallbacksインタフェースを実装する独自のクラスを書くことができますし、

getApplicaton().registerActivityLifecycleCallbacks(yourCustomClass); 

このクラスが受け取る提供Applicationクラスのインスタンス上でそのクラスを登録しますあなたの個々の活動と同じコールバック。がんばろう。

PS。これはAPIレベル14 btwなので、古い携帯電話では機能しません。

+1

@ClarkXPはい、継承リンクがアプリケーションクラスにとって強すぎます。これはlibに変換するのに十分なモジュールではありません。 – Snicolas

+0

'register'行を明確にするには:コールバッククラス(' 'Application.ActivityLifecycleCallbacks'を実装しています)で、そのコンストラクタで' 'getApplication()。registerActivityLifecycleCallbacks(this);'あなたのクラスが 'onCreate'または' initインスタンスがアクティブになったときに実行される同様のメソッドでは、コンストラクタではなく、その行を配置します(クラスは完全に準備が整うまでコールバックを受信したくないため)。 – ToolmakerSteve

+3

これは私には完璧に見えますが、unregisterActivityLifecycleCallbacks()メソッドをどこで呼び出すべきか不思議です。それは必須ではないのですか? – Amit

3

これを試してみてください:http://engineering.meetme.com/2015/04/android-determine-when-app-is-opened-or-closed/#comment-202

それはへAppForegroundStateManagerを提案し、このようにそのonStop()onStart()機能を介して各アクティビティレポート:

@Override 
protected void onStart() { 
    super.onStart(); 
    AppForegroundStateManager.getInstance().onActivityVisible(this); 
} 

@Override 
protected void onStop() { 
    AppForegroundStateManager.getInstance().onActivityNotVisible(this); 
    super.onStop(); 
} 

あなたApplicationクラスは、リスナーのように実装しています

public class MyApplication extends Application { 
    @Override 
    public void onCreate() { 
     super.onCreate(); 
     AppForegroundStateManager.getInstance().addListener(this); 
    } 

    @Override 
    public void onAppForegroundStateChange(AppForegroundStateManager.AppForegroundState newState) { 
     if (AppForegroundStateManager.AppForegroundState.IN_FOREGROUND.equals(newState)) { 
      // App just entered the foreground. Do something here! 
      Log.i(TAG, "App Just Entered the Foreground with launch mechanism of: " + mLaunchMechanism); 
     } else { 
      // App just entered the background. Set our launch mode back to the default of direct. 
      mLaunchMechanism = LaunchMechanism.DIRECT; 
     } 
    } 
} 

また、hoを決定するためのヒントとテクニックも含まれていますアプリが開かれた - 通知、アプリケーションを開くURL、またはAppsメニューから直接開きます。これは、ApplicationクラスにEnumを介して行われます:

public enum LaunchMechanism { 
    DIRECT, 
    NOTIFICATION, 
    URL, 
    BACKGROUND 
} 

private LaunchMechanism mLaunchMechanism = LaunchMechanism.DIRECT; 

public void setLaunchMechanism(LaunchMechanism launchMechanism) { 
    mLaunchMechanism = launchMechanism; 
} 

を、この私たちの実装では、我々は、ユーザーが携帯電話の呼び出しを行う場合のように、サードパーティの活動を開始します、我々は活動を開始したときのためのフラグを持っています私たちのアプリから、またはブラウザが起動されている場合。 - たとえば際に、デバイスの

if(!flag_userLaunchedThirdPartyActivity){ 
    AppForegroundStateManager.getInstance().onActivityNotVisible(this); 
    } 

アプリケーションがバックグラウンドに入るか否かを確認するために:起動アクティビティのonStop()では、我々はその後、活動がそれらのフラグが偽であるときではない視認性の報告だけに、このようなチェックを行います画面が暗くなったり、ユーザーが電話を受けた - それは次のように動作します。

public static boolean isApplicationGoingToBackground(final Context context) { 

    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 
    List<RunningTaskInfo> tasks = am.getRunningTasks(1); 
    if (!tasks.isEmpty()) { 
     ComponentName topActivity = tasks.get(0).topActivity; 
     if (!topActivity.getPackageName().equals(context.getPackageName())) { 
      setLaunchMechanism(LaunchMechanism.BACKGROUND); 
      return true; 
     } 
    } 

    setLaunchMechanism(LaunchMechanism.DIRECT); 
    return false; 
} 

このソリューションは、APIレベルに依存しないので、それはAPIレベルに戻ってすべての方法を動作するはずです。1.

0
@Override 
public void onCreate() { 
    super.onCreate(); 
    registerActivityLifecycleCallbacks(MyApplication.this/*(Your Application Name)*/); 

// registerActivityLifecycleCallbacks(MyApplication.this/(アプリケーション名)/ //唯一のすべてが良い

}

関連する問題