一、ActivityLifecycleCallbacks接口介绍

官方地址:https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks

在 Android API 14之后的Application类中,为我们提供了一个应用生命周期回调的注册方法,用来对应用的生命周期进行集中管理,这个接口叫registerActivityLifecycleCallbacks,可以通过它注册自己的ActivityLifeCycleCallback,每一个Activity的生命周期都会回调到这里的对应方法。

有了ActivityLifeCycleCallback接口,我们就可以完成之前我们想做的类似限制制定Activity个数等相关需求,因为所有Activity的生命周期都会在这里回调,我们可以根据条件随心处理。

Activity 的生命周期图为:https://developer.android.com/images/activity_lifecycle.png

ActivityLifecycleCallbacks 的方法列表文档:https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks

两者几乎是一一对应的,不管是做Activity的限制还是Activity的状态统计都是非常方便的,而且里面还有一个void onActivitySaveInstanceState(Activity activity, Bundle outState) 方法,非常方便我们来保存Activity状态数据。

使用ActivityLifecycleCallbacks我们可以完成类似如下的功能:

1. 限制指定的Activity的数量

2. 控制在特定情况下只会有一个Activity被打开

3. 判断App前后台状态

二、ActivityLifecycleCallbacks的应用

Application.ActivityLifecycleCallbacks是Application中的一个接口,使用起来也很简单,只需要调用registerActivityLifecycleCallbacks方法即可完成注册。Application.ActivityLifecycleCallbacks中对应的监听的生命周期方法会在Activity中的生命方法调用父类的方法之后被触发。

import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log; public class LifecycleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
init();
} private void init() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Created"+"activity==null "
+(activity==null)+" activity.isFinishing() "+(activity.isFinishing())+" activity.isDestroyed() "+activity.isDestroyed());
} @Override
public void onActivityStarted(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Started"+"activity==null "
+(activity==null)+" activity.isFinishing() "+(activity.isFinishing())+" activity.isDestroyed() "+activity.isDestroyed());
} @Override
public void onActivityResumed(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was oResumed"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
} @Override
public void onActivityPaused(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Pauseed"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
} @Override
public void onActivityStopped(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Stoped"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
} @Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.e("Lifecycle",activity.getLocalClassName()+" was SaveInstanceState"+"activity==null "
+(activity==null)+"activity.isFinishing() "+(activity.isFinishing())+"activity.isDestroyed() "+activity.isDestroyed());
} @Override
public void onActivityDestroyed(Activity activity) {
Log.e("Lifecycle",activity.getLocalClassName()+" was Destroyed"+"activity==null"
+(activity==null)+" activity.isFinishing() "+(activity.isFinishing())+" activity.isDestroyed()"+activity.isDestroyed());
}
});
}
}

在清单中声明Application,无需在Activity添加额外的代码就可以实现监控:

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View; public class MainActivity extends AppCompatActivity { public static final String LIFECYCLE = "MainActivity:Lifecycle"; @Override
protected void onCreate(Bundle savedInstanceState) {
Log.e(LIFECYCLE, "onCreate() is Running__before super.onCreate called");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(LIFECYCLE, "onCreate() is Running__after super.onCreate called");
} @Override
protected void onRestart() {
Log.e(LIFECYCLE, "onRestart() is Running__before super's called");
super.onRestart();
Log.e(LIFECYCLE, "onRestart() is Running__after super's called");
} @Override
protected void onStart() {
Log.e(LIFECYCLE, "onStart() is Running__before super.onStart called");
super.onStart();
Log.e(LIFECYCLE, "onStart() is Running__after super.onStart called");
} @Override
protected void onResume() {
Log.e(LIFECYCLE, "onResume() is Running__before super.onResume called");
super.onResume();
Log.e(LIFECYCLE, "onResume() is Running__after super.onResume called");
} @Override
protected void onPause() {
Log.e(LIFECYCLE, "onPause() is Running__before super's called");
super.onPause();
Log.e(LIFECYCLE, "onPause() is Running__after super's called");
} @Override
protected void onStop() {
Log.e(LIFECYCLE, "onStop() is Running__before super's called");
super.onStop();
Log.e(LIFECYCLE, "onStop() is Running__after super's called");
} @Override
protected void onDestroy() {
Log.e(LIFECYCLE, "onDestroy() is Running__before super's called");
super.onDestroy();
Log.e(LIFECYCLE, "onDestroy() is Running__after super's called");
} public void toTask(View view) {
startActivity(new Intent(this, TaskActivity.class));
//finish();
}

三、使用 ActivityLifecycleCallbacks 判断App前后台状态

App 前后台的切换一般情况下都是按Home来进行,当然也有别的方式,但是此时Activity的生命周期是一样的:

HOME键前后台切换Activity的执行顺序:onPause->onStop->onRestart->onStart->onResume

BACK键前后台切换Activity键的顺序: onPause->onStop->onDestroy->onCreate->onStart->onResume

其实按BACK按键就是退出app了,不算是前台后切换。

现在我们知道App的由前台切换到后台所有打开的Activity会走:

onPause->onStop

后台切换到前台所有打开的Activity会走:

->onRestart->onStart->onResume

前后台切换App所有打开的Activity的生命周期都是一样的,这样我就可以在ActivityLifecycleCallbacks回调接口中记录生命周期:

public class App extends Application {
//记录Activity的总个数
public int count = 0;
private static App mApp;
public static Stack<ActivityDetail> store;
//商品详情页最多个数,这里为了测试只写了2,大家根据自己的情况设值
private static final int MAX_ACTIVITY_DETAIL_NUM = 2; @Override
public void onCreate() {
super.onCreate();
mApp = this;
store = new Stack<>();
registerActivityLifecycleCallbacks(new SwitchBackgroundCallbacks());
} public static App getAppContext() {
return mApp;
} public static boolean toGoodsDetail(String id){ if(store == null || store.empty()){
return false;
}
for(ActivityDetail activityDetail : store){
if(id.equalsIgnoreCase(activityDetail.getID())){ //当前商品的详情页已经打开
activityDetail.finish();
// 这是你需要在AndroidManifest.xml中添加"Android.permission.STOP_APP_SWITCHES"用户权限,前提是必须是系统应用才可以。
// ActivityManager am = (ActivityManager) getAppContext().getSystemService(Activity.ACTIVITY_SERVICE);
// am.moveTaskToFront(activityDetail.getTaskId(), 0);
return true;
}
}
return false;
} private class SwitchBackgroundCallbacks implements ActivityLifecycleCallbacks { @Override
public void onActivityCreated(Activity activity, Bundle bundle) {
if(activity instanceof ActivityDetail) {
if(store.size() >= MAX_ACTIVITY_DETAIL_NUM){
store.peek().finish(); //移除栈底的详情页并finish,保证商品详情页个数最大为10
}
store.add((ActivityDetail) activity);
}
} @Override
public void onActivityStarted(Activity activity) {
if (count == 0) { //后台切换到前台
Log.v("danxx", ">>>>>>>>>>>>>>>>>>>App切到前台");
}
count++;
} @Override
public void onActivityResumed(Activity activity) { } @Override
public void onActivityPaused(Activity activity) { } @Override
public void onActivityStopped(Activity activity) {
count--;
if (count == 0) { //前台切换到后台
Log.v("danxx", ">>>>>>>>>>>>>>>>>>>App切到后台");
}
} @Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { } @Override
public void onActivityDestroyed(Activity activity) {
store.remove(activity);
}
}
// 获取当前的Activity
public Activity getCurActivity() {
return store.lastElement();
}
}

最新文章

  1. 备忘-Sql server Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置
  2. 传智播客--高级控件--showdialog关闭(小白内容)
  3. Java如何解决脆弱基类(基类被冻结)问题
  4. JavaEE基础(十五)/集合
  5. PHP脚本memcache类的源码
  6. 如何快速清除.svn文件
  7. 打印print
  8. delphi中locate方法
  9. Tomcat内存溢出(java.lang.OutOfMemoryError: PermGen space)的解决办法
  10. Hbase常用命令
  11. linux 查看端口是否被占用
  12. 关于国际化中的$NON-NLS-1$
  13. WebClient.UploadValues Post中文乱码的解决方法
  14. Maven : 将Jar安装到本地仓库和Jar上传到私服 转
  15. Arcgis API for Android之GPS定位
  16. spring cloud微服务搭建第一天
  17. Peaceful Commission
  18. Python Learning: 02
  19. AIOps指导
  20. 黑马程序员_java基础笔记(13)...类加载器和代理

热门文章

  1. dubbo 订阅 RPC 服务
  2. 2017 CCPC秦皇岛 A题 A Ballon Robot
  3. numpy的基本API(三)——索引
  4. Redis第二讲【Redis基本命令和五大数据结构】
  5. Weed3 for java 新的微型ORM框架
  6. 一线大厂Java面试必问的2大类Tomcat调优
  7. Winform修改配置文件节点保存到配置文件
  8. 《Java Spring框架》基于IDEA搭建Spring源码
  9. pip和conda添加国内清华镜像源(亲测有效)
  10. UWP 利用Windows.UI.Composition实现简单的放大&#128269;效果