在某些特定的場景下,我們需要判斷App是否進入後臺運行狀態。然後根據App處在前臺/後臺分別進行不同的操作行爲。我們可以通過Activity的生命週期來,實現這一需求。
關於生命週期,我們可以分類爲三個類別:
1:entire lifetime(完整生命週期)
onCreate -> onStart -> onResume -> onPause -> onStop -> onDestroy.
2:visible lifetime(可見生命週期)
onStart -> onResume -> onPause -> onStop
3:foreground lifetime(前臺生命週期)
onResume -> onPause
根據上面,當應用處於前臺,當前Activity一定調用了onResume方法,而應用進入後臺時,一定會調用onPause方法。根據這個原理,我們利用Activity生命週期來判斷應用的前後臺運行狀態。很輕鬆的獲取了各種情境下應用的前後臺狀態變換。
上代碼:
package mo.yumf.com.myviews;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 在Application類中監聽App處於前臺和後臺
*/
public class ForegroundCallbacks implements Application.ActivityLifecycleCallbacks {
public static final long CHECK_DELAY = 500;
public static final String TAG = ForegroundCallbacks.class.getName();
public interface Listener {
void onBecameForeground();
void onBecameBackground();
}
private static ForegroundCallbacks instance;
private boolean foreground = false, paused = true;
private Handler handler = new Handler();
private List<Listener> listeners = new CopyOnWriteArrayList<>();
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){
Log.e("yumf","went foreground");
for (Listener l : listeners) {
try {
l.onBecameForeground();
} catch (Exception exc) {
Log.e("yumf","Listener threw exception!");
}
}
} else {
Log.e("yumf","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;
Log.e("yumf","went background");
for (Listener l : listeners) {
try {
l.onBecameBackground();
} catch (Exception exc) {
Log.e("yumf","Listener threw exception!", exc);
}
}
} else {
Log.e("yumf","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) {}
}
在Application類中:
public class MyApplication extends Application {
private int mCount;
@Override
public void onCreate() {
super.onCreate();
ForegroundCallbacks callbacks = ForegroundCallbacks.get(this);
callbacks.addListener(new ForegroundCallbacks.Listener() {
@Override
public void onBecameForeground() {
Log.i("yumf","====foreground");
}
@Override
public void onBecameBackground() {
Log.i("yumf","====background");
}
});
}
}