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?
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.
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.
, 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.
@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
}