参考:
手持ActivityLifecycleCallbacks,监听前后台状态如此舒服
判断App位于前台或者后台的6种方法
Android对App前后台运行状态的判断
有多种方式可以监听,以下只拿常见的三种来讲(推荐第三种)
1、 getRunningTasks
public static boolean isRunningForeground (Context context) {
ActivityManager am = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = am.getRunningTasks(1).get(0).topActivity;
String currentPackageName = cn.getPackageName();
if(!TextUtils.isEmpty(currentPackageName) && currentPackageName.equals(context.getPackageName())) {
return true ;
}
return false ;
}
2、 getRunningAppProcesses
public static boolean isAppForeground(Context context){
ActivityManager activityManager = (ActivityManager) context.getSystemService(Service.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfoList = activityManager.getRunningAppProcesses();
if (runningAppProcessInfoList==null){
return false;
}
for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcessInfoList) {
if (processInfo.processName.equals(context.getPackageName()) &&
processInfo.importance==ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
return true;
}
}
return false;
}
3、 ActivityLifecycleCallbacks(推荐)
创建Application.ActivityLifecycleCallbacks的实现类,并调用application.registerActivityLifecycleCallbacks(callback)方法注册监听,之后在callback的生命周期方法里面进行判断是否由后台进入前台,或是又前台进入后台,这部分下面细讲。
3种方法比较
以下是我找到的实现类,来自手持ActivityLifecycleCallbacks,监听前后台状态如此舒服
public class ForegroundCallbacks implements Application.ActivityLifecycleCallbacks {
public static final long CHECK_DELAY = 500;
public static final String TAG = ForegroundCallbacks.class.getName();
public interface Listener {
public void onBecameForeground();
public void onBecameBackground();
}
private static ForegroundCallbacks instance;
private boolean foreground = false, paused = true;
private Handler handler = new Handler();
private List<Listener> listeners = new CopyOnWriteArrayList<Listener>();
private Runnable check;
public static ForegroundCallbacks init(Application application){
if (instance == null) {
instance = new ForegroundCallbacks();
application.registerActivityLifecycleCallbacks(instance);
}
return instance;
}
public static ForegroundCallbacks get(Application application){
if (instance == null) {
init(application);
}
return instance;
}
public static ForegroundCallbacks get(Context ctx){
if (instance == null) {
Context appCtx = ctx.getApplicationContext();
if (appCtx instanceof Application) {
init((Application)appCtx);
}
throw new IllegalStateException(
"Foreground is not initialised and " +
"cannot obtain the Application object");
}
return instance;
}
public static ForegroundCallbacks get(){
if (instance == null) {
throw new IllegalStateException(
"Foreground is not initialised - invoke " +
"at least once with parameterised init/get");
}
return instance;
}
public boolean isForeground(){
return foreground;
}
public boolean isBackground(){
return !foreground;
}
public void addListener(Listener listener){
listeners.add(listener);
}
public void removeListener(Listener listener){
listeners.remove(listener);
}
@Override
public void onActivityResumed(Activity activity) {
paused = false;
boolean wasBackground = !foreground;
foreground = true;
if (check != null)
handler.removeCallbacks(check);
if (wasBackground){
LogUtil.e(TAG, "went foreground");
for (Listener l : listeners) {
try {
l.onBecameForeground();
} catch (Exception exc) {
LogUtil.e(TAG, "Listener threw exception!: " + exc);
}
}
} else {
LogUtil.e(TAG, "still foreground");
}
}
@Override
public void onActivityPaused(Activity activity) {
paused = true;
if (check != null)
handler.removeCallbacks(check);
handler.postDelayed(check = new Runnable(){
@Override
public void run() {
if (foreground && paused) {
foreground = false;
LogUtil.e(TAG, "went background");
for (Listener l : listeners) {
try {
l.onBecameBackground();
} catch (Exception exc) {
LogUtil.e(TAG, "Listener threw exception!: " + exc);
}
}
} else {
LogUtil.e(TAG, "still foreground");
}
}
}, CHECK_DELAY);
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
@Override
public void onActivityStarted(Activity activity) {}
@Override
public void onActivityStopped(Activity activity) {}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
@Override
public void onActivityDestroyed(Activity activity) {}
}
分析:
首先生命周期肯定是要了解的,两个activity跳转的生命周期如下:
08-25 05:02:47.783: INFO/System.out(339): MainActivity------->onPause()
08-25 05:02:47.843: INFO/System.out(339): Another------->onCreate()
08-25 05:02:47.853: INFO/System.out(339): Another------->onStart()
08-25 05:02:47.853: INFO/System.out(339): Another------->onResume()
08-25 05:02:48.253: INFO/System.out(339): MainActivity------->onStop()
主要是在onActivityResumed和onActivityPaused里面对foreground和paused这两个值进行判断。
- onActivityResumed里判断!foreground == true,则视为进入前台,并把foreground置为true。
- onActivityPaused里判断当前是前台(foreground =
true),且500ms内没有启动新的页面(onActivityResumed被调用),则视为进入后台,并把foreground置为false。
大功告成!