App监听前后台变化是非常常见的一个需求,我们需要在App切到前台或者后台之后,做一些业务逻辑处理,比如提示用户app进入后台,那么如何监听App前后台变化呢?
1.context.registerActivityLifecycleCallbacks 方式
class MyApp extends Application{
private int mTopActivityCount = 0;
private void registerActivityLifecycle() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
mTopActivityCount++;
if(mTopActivityCount==1){
//app处于前台
}
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
mTopActivityCount--;
if(mTopActivityCount==0){
//app处于后台
}
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
});
}
}
实际效果:计数不准,判断前后台不准
2.通过使用 ProcessLifecycleOwner
ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
switch (event){
case ON_START:
//前台时回调
break;
case ON_RESUME:
//前台时回调
break;
case ON_STOP:
//后台时回调
break;
case ON_PAUSE:
//后台时回调
break;
}
}
});
其实源码和方式1基本上一致,唯一的区别就是前后台判断是增加了700毫秒的延迟,那么问题就来了,这个700毫秒是如何确定的呢?所以实际中在不同的手机中效果还是不一致,不准。
3.精准方案通过闲时消息机制+进程判断
/**
* app进入后台
*/
private boolean mAppIsBackground = true;
private void registerActivityLifecycle() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(@NonNull Activity activity) {
if (mAppIsBackground) {
//app进入前台
}
}
@Override
public void onActivityResumed(@NonNull Activity activity) {
}
@Override
public void onActivityPaused(@NonNull Activity activity) {
}
@Override
public void onActivityStopped(@NonNull Activity activity) {
Looper.getMainLooper().getQueue().addIdleHandler(new MessageQueue.IdleHandler() {
@Override
public boolean queueIdle() {
ActivityManager activityManager = (ActivityManager) activity
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager
.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(activity.getPackageName())) {
if (appProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
//app进入后台
mAppIsBackground = true;
}
}
}
return false;
}
});
}
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
});
}