监听app前后台切换对于App来说是一个比较实用的功能。一些功能的实现离不开前后台切换的时机,比如App进入前台检查剪切板、统计用户在线时间等等。下面本文就从前后台切换监听说起。 App前后台切换,本质上就是当前App任务栈顶页面的 在App的基类BaseActivity中监听 具体实现: 这个方案能够监听到App的前后台切换,但也仅限于全部页面继承自BaseActivity才可以准确的获取切换时机。 若有页面没有继承BaseActivity,则获取的监听回调可能是错误的! 还是在基类BaseActivity中做文章。我们可以在 具体实现: 在Application类中,提供了一个应用生命周期回调的注册方法,用来对应用的生命周期进行集中管理,这个接口叫 在Application的 为什么要判断启动呢?这里有个概念是从桌面点击icon进入App不算是严格意义上的回到前台,而是启动App到达了前台,因此需要添加一个启动校验放在方法中标识。 因此在上述三个方案中都可以按照该方法来监听启动。 相应的,前后台切换监听也要做如下修改:
onPause和onResume方法被调用了,并且页面onPause后回到了桌面或者切换到其他App。在Android系统中并未有App到前后台相关的广播,因此我们只能在App自己实现相关的监听方法。方案1
Activity的onStart和onStop方法。在onStart方法内部记录当前类名和hash值,并且在onStop方法内将记录拿出对比,若类名和hash值一致,则说明App没有进行页面内的跳转,而是被用户切换到后台。 public void onResume() {
String topActivityName = PublicPreferencesUtils.getTopActivityName();
boolean isBackByHome = PublicPreferencesUtils.isBackByHome();
if(isBackByHome && mActivityName.equals(topActivityName)) {
// 表示由Home键回到程序,而且程序的进程没有被杀掉
mHomeClickListener.onClickToFront();
}
PublicPreferencesUtils.saveTopActivityName(mActivityName);
PublicPreferencesUtils.saveBackByHome(false); // 重置
}
public void onStop() {
if(!mActivity.isFinishing()){ // 如果程序没有退出
String topActivityName = PublicPreferencesUtils.getTopActivityName();
if(mActivityName.equals(topActivityName)) {
// 则表示用户按了Home键,程序进入后台运行
mHomeClickListener.onClickToBack();
// 保存是按Home键进入的后台
PublicPreferencesUtils.saveBackByHome(true);
}
}
}
方案2
onStop方法里添加对于当前前台进程的判断。若前台进程为当前应用进程,则认为App正在前台显示,否则切换到了后台。 public boolean isRunningForeground() {
ActivityManager activityManager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcessInfos = activityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessInfos) {
if (appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
if (appProcessInfo.processName.equals(this.getApplicationInfo().processName)) {
Log.d(TAG,"App isRunningForeGround");
return true;
}
}
}
Log.d(TAG, "App isRunningBackGround");
return false;
}
方案3
registerActivityLifecycleCallbacks,可以通过它注册自己的ActivityLifeCycleCallback,每一个Activity的生命周期都会回调到这里的对应方法。其实这个注册方法的本质和我们实现BaseActivity是一样的,只是将生命周期的管理移到了Activity本身的实现中。public class ForegroundHelper implements Application.ActivityLifecycleCallbacks {
//launch页标记
private static final String LAUNCH_ACTIVITY_TAG = LaunchActivity.TAG;
//当前记录的Activity个数
private int finalCount;
//回调listener
private CopyOnWriteArrayList<AppStatusListener> mListeners;
private ForegroundHelper() {
mListeners = new CopyOnWriteArrayList<>();
}
public static ForegroundHelper getInstance() {
return Singleton.mInstance;
}
/**
* 添加监听
*
* @param appStatusListener
*/
public void addAppStatusListener(AppStatusListener appStatusListener) {
mListeners.add(appStatusListener);
}
/**
* 移除监听
*
* @param appStatusListener
*/
public void removeAppStatusListener(AppStatusListener appStatusListener) {
mListeners.remove(appStatusListener);
}
···省略部分代码···
@Override
public void onActivityStarted(Activity activity) {
finalCount++;
//如果mFinalCount ==1,说明是从后台到前台
LOGGER.d("ForegroundHelper", finalCount + "");
if (finalCount == 1) {
boolean isAppStart = checkAppStart(activity);
//说明从后台回到了前台
LOGGER.d("ForegroundHelper", isAppStart ? "app启动了" : "从后台回到了前台");
notifyForeground(isAppStart);
}
}
private boolean checkAppStart(Activity activity) {
boolean result = false;
if (activity.getClass().getSimpleName().equals(LAUNCH_ACTIVITY_TAG)) {
result = activity.isTaskRoot();
}
return result;
}
@Override
public void onActivityStopped(Activity activity) {
finalCount--;
//如果mFinalCount ==0,说明是前台到后台
LOGGER.d("ForegroundHelper", finalCount + "");
if (finalCount == 0) {
//说明从前台回到了后台
LOGGER.d("ForegroundHelper", "从前台到了后台");
notifyBackground();
}
}
···省略部分代码···
onCreate方法中添加registerActivityLifecycleCallbacks(ForegroundHelper.getInstance())即可监听到App前后台启动的时机。判断启动
若当前启动的是LaunchActivity,并且不在栈底的话,则认为是App启动到了前台。 //检查是否是启动App
private boolean checkAppStart(Activity activity) {
boolean result = false;
if (activity.getClass().getSimpleName().equals(LAUNCH_ACTIVITY_TAG)) {
result = activity.isTaskRoot();
}
return result;
}
/**
* App前后台切换监听
*/
public interface AppStatusListener {
/**
* app 到前台
*
* @param appStart 是否是App 启动
*/
void onForeground(boolean appStart);
/**
* App切换到后台
*/
void onBackground();
}
支付宝扫码打赏
微信打赏