Автоматически регистрировать события жизненного цикла Android с помощью ActivityLifecycleCallbacks?
Я пытаюсь автоматически фиксировать и регистрировать события жизненного цикла Android с помощью ActivityLifecycleCallbacks, однако документации по этому вопросу, мягко говоря, мало:
public void registerActivityLifecycleCallbacks (Application.ActivityLifecycleCallbacks callback)
Я не хочу расширять класс Activity или переопределять существующие методы жизненного цикла (onCreate, onResume и т.д.) Я хочу, чтобы отдельный класс прослушивал эти события и действовал соответствующим образом.
У кого-нибудь есть опыт в этом или есть ссылки на хорошую надежную документацию или руководства о том, как это работает? В частности, как зарегистрироваться для ActivityLifecycleCallbacks и как с ними обращаться?
Переведено автоматически
Ответ 1
У меня нет личного опыта, но, судя по API, вы можете просто написать свой собственный класс, который реализует Application.ActivityLifecycleCallbacks
интерфейс, и зарегистрировать этот класс в предоставленном Application
экземпляре класса
getApplicaton().registerActivityLifecycleCallbacks(yourCustomClass);
Этот класс будет получать те же обратные вызовы, что и ваши индивидуальные действия. Удачи.
PS. Кстати, это API 14-го уровня, поэтому на старых телефонах это не сработает.
Ответ 2
Я создал свою собственную реализацию Application.ActivityLifecycleCallbacks
. Я использую SherlockActivity
, но для обычного класса Activity может сработать.
Во-первых, я создаю интерфейс, в котором есть все методы для отслеживания жизненного цикла действий:
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);
}
}
В-четвертых, все классы, которые расширяются от 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.
Ответ 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;
}
}
}
Он также включает советы и рекомендации по определению способа открытия приложения - из уведомления, URL-адреса, открывающего ваше приложение, или непосредственно из меню приложений. Это делается с помощью Enum
в классе Application:
public enum LaunchMechanism {
DIRECT,
NOTIFICATION,
URL,
BACKGROUND
}
private LaunchMechanism mLaunchMechanism = LaunchMechanism.DIRECT;
public void setLaunchMechanism(LaunchMechanism launchMechanism) {
mLaunchMechanism = launchMechanism;
}
В нашей реализации этого у нас есть флаги, указывающие, когда мы запускаем действие, которое запускает стороннее действие, например, если пользователь совершает телефонный звонок из нашего приложения или запускается браузер. Затем при запуске activity onStop()
мы выполняем проверку, подобную этой, чтобы сообщать о невидимости activity только тогда, когда эти флаги имеют значение 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.
Ответ 4
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(MyApplication.this/*(Your Application Name)*/);
}
Добавьте эту строку только в класс приложения, и все будет работать хорошо.