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