36

ActivityLifecycleCallbacksを使用してAndroidライフサイクルイベントを自動的にキャプチャしてログに記録しようとしていますが、控えめに言っても、この問題に関するドキュメントはほとんどありません。

    public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)

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

誰かがこれについて何か経験がありますか、またはこれがどのように機能するかについての優れた堅実なドキュメントまたはチュートリアルへのリンクを持っていますか?具体的には、ActivityLifecycleCallbacksに登録する方法と、それらを処理する方法を教えてください。

4

4 に答える 4

57

私は直接の経験はありませんが、APIから判断すると、Application.ActivityLifecycleCallbacksインターフェイスを実装する独自のクラスを作成し、提供されたApplicationクラスインスタンスにそのクラスを登録することができます。

getApplicaton().registerActivityLifecycleCallbacks(yourCustomClass);

このクラスは、個々のアクティビティと同じコールバックを受け取ります。幸運を。

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

于 2012-06-18T11:57:22.893 に答える
36

私はの独自の実装を行いApplication.ActivityLifecycleCallbacksました。を使用してSherlockActivityいますが、通常のアクティビティクラスでは機能する可能性があります。

まず、アクティビティのライフサイクルを追跡するためのすべてのメソッドを備えたインターフェイスを作成しています。

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);
}

次に、このインターフェイスをアプリケーションのクラスに実装しました。

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());
    }
}

第三に、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
        super.onResume();
        nMyApplication.onActivityResumed(this);
    }

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

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

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

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

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

第4に、SherlockActivityから拡張するすべてのクラスを、MySherlockActivityに置き換えました。

public class MainActivity extends MySherlockActivity{

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

}

これで、logcatに、MyApplicationで作成されたインターフェイス実装でプログラムされたログが表示されます。

アップデート

この実装は、APIレベル9(Gingerbread)、APIレベル12(Honeycomb)、およびAPIレベル17(Jelly Bean)からテストされ、正常に動作します。Androidの古いバージョンで動作する可能性があります。

于 2013-01-23T00:12:00.460 に答える
5
@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(MyApplication.this/*(Your Application Name)*/);
}

この行をApplicationクラスに追加するだけで、すべて正常に機能します。

于 2017-11-16T07:18:18.973 に答える
4

これを試してください: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;
        }
    }
}

また、通知、アプリを開くURLから、または[アプリ]メニューから直接、アプリがどのように開かれたかを判断するためのヒントとコツも含まれています。これはEnum、Applicationクラスのを介して行われます。

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

private LaunchMechanism mLaunchMechanism = LaunchMechanism.DIRECT;

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

これの実装では、ユーザーがアプリから電話をかけた場合やブラウザーが起動された場合など、サードパーティのアクティビティを起動するアクティビティを開始するタイミングのフラグがあります。起動アクティビティでは、次のonStop()ようなチェックを実行して、これらのフラグがfalseの場合にのみアクティビティの非表示を報告します。

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

アプリケーションがバックグラウンドに移行するかどうかを確認する場合(たとえば、デバイスの画面が暗くなる場合やユーザーが電話を受信する場合)、次のように機能します。

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までさかのぼって機能するはずです。

于 2015-04-28T11:14:03.577 に答える