J'essaie de capturer et de consigner automatiquement Android événements de cycle de vie en utilisant ActivityLifecycleCallbacks, cependant la documentation sur ce sujet est rare, pour dire le moins:
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 séparée à l'écoute de ces événements et à agir en conséquence.
Quelqu'un a-t-il une expérience dans ce domaine ou a-t-il des liens vers une bonne documentation solide ou des tutoriels sur la façon dont cela fonctionne? Plus précisément, comment s'inscrire à ActivityLifecycleCallbacks et comment les gérer?
J'ai fait ma propre implémentation de Application.ActivityLifecycleCallbacks
. J'utilise SherlockActivity
, mais pour une classe d'activité normale, cela 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
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);
}
}
Quatrièmement, toutes les classes qui s'étendent de SherlockActivity, j'ai remplacé 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 de l'API Niveau 9 (Gingerbread), de l'API Level 12 (Honeycomb) et de l'API Level 17 (Jelly Bean) et fonctionne très bien. Pourrait fonctionner 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. Il s'agit du niveau 14 API btw, donc cela 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 celui-ci:
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, d'une URL ouvrant votre application ou directement à partir du menu Applications. Cela se fait via un Enum
dans la classe 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 cela, nous avons des drapeaux pour quand nous démarrons une activité qui lancera une activité tierce, comme si l'utilisateur fait un appel téléphonique depuis notre application ou si un navigateur est lancé. Dans la onStop()
de l'activité de lancement, nous effectuons une vérification comme celle-ci pour signaler uniquement 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 en arrière-plan - par exemple lorsque l'écran de l'appareil s'assombrit ou lorsque l'utilisateur reçoit un appel téléphonique - cela 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 d'API, elle devrait donc remonter jusqu'au niveau d'API 1.
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(MyApplication.this/*(Your Application Name)*/);
// registerActivityLifecycleCallbacks (MyApplication.this/(Votre nom d'application)/// n'ajoutez cette ligne qu'à la classe Application tout fonctionne bien
}