Enregistrez automatiquement les événements du cycle de vie Android en utilisant ActivityLifecycleCallbacks?

J'essaie de capturer et de consigner automatiquement les événements du cycle de vie Android en utilisant ActivityLifecycleCallbacks, mais la documentation à ce sujet est pour le moins rare:

    public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)

Je ne veux pas avoir à étendre la classe Activity ou à remplacer les méthodes de cycle de vie existantes (onCreate, onResume, etc...) Je cherche à avoir une classe distincte à écouter ces événements et à agir en conséquence.

Quelqu'un a une expérience dans ce, ou des liens vers de bonnes et solides documentation ou tutoriels sur la façon dont cela fonctionne? Plus précisément, comment s'inscrire à ActivityLifecycleCallbacks, et comment les gérer?

24
demandé sur AWT 2012-05-15 22:07:16

4 réponses

J'ai fait ma propre mise en œuvre de Application.ActivityLifecycleCallbacks. J'utilise SherlockActivity, mais pour la classe D'activité normale pourrait fonctionner.

Tout d'abord, je crée une interface qui a toutes les méthodes pour suivre le cycle de vie des activités:

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

Deuxièmement, j'ai implémenté cette interface dans la classe de mon Application:

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

Troisièmement, je crée une classe qui s'étend de 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);
    }   
}

Quatrièmement, toutes les classes qui s'étendent de SherlockActivity, j'ai remplacé pour MySherlockActivity:

public class MainActivity extends MySherlockActivity{

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

}

Maintenant, dans le logcat, vous verrez les journaux programmés dans L'implémentation de L'Interface faite dans MyApplication.

Mise à JOUR

Cette implémentation a été testée à partir du niveau API 9 (Gingerbread), du niveau API 12 (Honeycomb) et du niveau API 17 (Jelly Bean) et fonctionne correctement. Pourrait fonctionne dans les anciennes versions D'Android.

31
répondu ClarkXP 2013-10-22 22:09:20

Je n'ai aucune expérience de première main mais à en juger par l'API, vous pouvez simplement écrire votre propre classe qui implémente le Application.ActivityLifecycleCallbacks interface et enregistrez cette classe sur l'instance de classe Application fournie

getApplicaton().registerActivityLifecycleCallbacks(yourCustomClass);

Cette classe recevra les mêmes rappels que vos activités individuelles. Bonne chance.

PS. Ceci est API Niveau 14 btw, donc il ne fonctionnera pas sur les téléphones plus anciens.

41
répondu Jeroen 2013-10-22 22:08:22

, Essayez ceci: http://engineering.meetme.com/2015/04/android-determine-when-app-is-opened-or-closed/#comment-202

Il propose un AppForegroundStateManager auquel chaque activité rend compte à travers ses fonctions onStop() et onStart() comme ceci:

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

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

Votre classe Application implémente un écouteur comme ceci:

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

Il comprend également des conseils et astuces pour déterminer comment l'application a été ouverte-à partir d'une notification, une URL d'ouverture de votre application ou directement à partir du menu Applications. C'est fait par un Enum dans la classe D'Application:

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

private LaunchMechanism mLaunchMechanism = LaunchMechanism.DIRECT;

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

Dans notre implémentation de ceci, nous avons des indicateurs pour quand nous commençons une activité qui lancera une activité tierce, comme si l'utilisateur fait un appel téléphonique de notre application ou si un navigateur est lancé. Dans onStop() de l'activité de lancement, nous effectuons alors une vérification comme celle-ci pour ne signaler que la non-visibilité de l'activité lorsque ces indicateurs sont faux:

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

Pour vérifier si l'application passe ou non en arrière-plan - par exemple lorsque l'écran de l'appareil s'éteigne ou que l'utilisateur reçoit un appel téléphonique qu'il fonctionne comme ceci:

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

Cette solution ne dépend pas d'un niveau API, elle devrait donc fonctionner jusqu'au niveau API 1.

3
répondu marienke 2015-04-28 11:14:03
@Override
public void onCreate() {
    super.onCreate();
    registerActivityLifecycleCallbacks(MyApplication.this/*(Your Application Name)*/);

/ / registerActivityLifecycleCallbacks (MyApplication.this / (Nom de votre Application) / // seulement ajouter cette ligne sur la classe D'Application tout fonctionne bien

}

0
répondu Anand Raj Mehta 2017-11-16 07:18:18