From e4a4bf0fc3f2f7fd294077b9b82136f76c57ec5d Mon Sep 17 00:00:00 2001 From: whmbuaa Date: Wed, 27 Apr 2016 18:02:02 +0800 Subject: [PATCH] the previous implemention has some pre-condition which is not always true. the previous implemention has a pre-condition: 1. ActivityA->ActivityB 2. press back 2.1 ActivityA.onStart 2.1 ActivityB.onStop otherwize, the behavior will be wrong. unfornautely, this assumption is not always true. So I make a new version. Please review and give your comments. Thanks! --- .../java/com/sjl/foreground/Foreground.java | 192 ++++++------------ 1 file changed, 65 insertions(+), 127 deletions(-) diff --git a/Foredroid/src/main/java/com/sjl/foreground/Foreground.java b/Foredroid/src/main/java/com/sjl/foreground/Foreground.java index aa1b0ea..6d94c7f 100644 --- a/Foredroid/src/main/java/com/sjl/foreground/Foreground.java +++ b/Foredroid/src/main/java/com/sjl/foreground/Foreground.java @@ -57,177 +57,115 @@ * Foreground.get(getApplication()).removeListener(listener); * } */ -public class Foreground implements Application.ActivityLifecycleCallbacks { - - public static final String TAG = Foreground.class.getName(); - public static final long CHECK_DELAY = 2000; +public class Foreground implements Application.ActivityLifecycleCallbacks { public interface Listener { public void onBecameForeground(); public void onBecameBackground(); } - public interface Binding { - public void unbind(); - } + private static Foreground sInstance; + private List> mListenerList; + private boolean mIsForeground; + private Stack mActivityStack; - private interface Callback { - public void invoke(Listener listener); + private Foreground(){ + mListenerList = new LinkedList>(); + mActivityStack = new Stack(); } - private static class Listeners { - private List> listeners = new CopyOnWriteArrayList<>(); - - public Binding add(Listener listener){ - final WeakReference wr = new WeakReference<>(listener); - listeners.add(wr); - return new Binding(){ - public void unbind() { - listeners.remove(wr); - } - }; + public static final void init(Application app){ + if(sInstance == null){ + sInstance = new Foreground(); + app.registerActivityLifecycleCallbacks(sInstance); } - public void each(Callback callback){ - for (Iterator> it = listeners.iterator(); it.hasNext();) { - try { - WeakReference wr = it.next(); - Listener l = wr.get(); - if (l != null) - callback.invoke(l); - else - it.remove(); - } catch (Exception exc) { - Log.e(TAG, "Listener threw exception!", exc); - } - } - } + } + public static final Foreground getInstance(){ + return sInstance; } - private static Callback becameForeground = new Callback() { - @Override - public void invoke(Listener listener) { - listener.onBecameForeground(); + private void notifyToForeground(){ + for(WeakReference listenerRef : mListenerList){ + Listener listener = listenerRef.get(); + if(listener != null){ + listener.onBecameForeground(); + } } - }; + } - private static Callback becameBackground = new Callback() { - @Override - public void invoke(Listener listener) { - listener.onBecameBackground(); + private void notifyToBackground(){ + for(WeakReference listenerRef : mListenerList){ + Listener listener = listenerRef.get(); + if(listener != null){ + listener.onBecameBackground(); + } } - }; - - private static Foreground instance; + } - private boolean foreground; - private Activity current; - private Listeners listeners = new Listeners(); - private Handler handler = new Handler(); - private Runnable check; + public Activity getTopActivity(){ - public static Foreground init(Application application){ - if (instance == null) { - instance = new Foreground(); - application.registerActivityLifecycleCallbacks(instance); - } - return instance; + return mActivityStack.peek(); } - - public static Foreground get(Application application){ - if (instance == null) { - init(application); - } - return instance; + public void addListener(Listener listener){ + WeakReference listenerWeakRef = new WeakReference(listener); + mListenerList.add(listenerWeakRef); } - - public static Foreground get(){ - if (instance == null) { - throw new IllegalStateException( - "Foreground is not initialised - first invocation must use parameterised init/get"); + public void removeListener(Listener listener){ + for(WeakReference listenerRef : mListenerList){ + Listener tempListener = listenerRef.get(); + if(tempListener == listener){ + mListenerList.remove(listenerRef); + return; + } } - return instance; } - public boolean isForeground(){ - return foreground; - } + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { - public boolean isBackground(){ - return !foreground; } - public Binding addListener(Listener listener){ - return listeners.add(listener); + @Override + public void onActivityStarted(Activity activity) { + + if(!mIsForeground){ + mIsForeground = true; + notifyToForeground(); + } + mActivityStack.push(activity); } @Override - public void onActivityResumed(Activity activity) {} + public void onActivityResumed(Activity activity) { - @Override - public void onActivityPaused(Activity activity) { - // if we're changing configurations we aren't going background so - // no need to schedule the check - if (!activity.isChangingConfigurations()) { - // don't prevent activity being gc'd - final WeakReference ref = new WeakReference<>(activity); - handler.postDelayed(check = new Runnable() { - @Override - public void run() { - onActivityCeased(ref.get()); - } - }, CHECK_DELAY); - } } @Override - public void onActivityStarted(Activity activity) { - current = activity; - // remove any scheduled checks since we're starting another activity - // we're definitely not going background - if (check != null) { - handler.removeCallbacks(check); - } + public void onActivityPaused(Activity activity) { - // check if we're becoming foreground and notify listeners - if (!foreground && (activity != null && !activity.isChangingConfigurations())){ - foreground = true; - Log.w(TAG, "became foreground"); - listeners.each(becameForeground); - } else { - Log.i(TAG, "still foreground"); - } } @Override public void onActivityStopped(Activity activity) { - if (check != null) { - handler.removeCallbacks(check); + mActivityStack.remove(activity); + if((mActivityStack.isEmpty())&&(!activity.isChangingConfigurations())){ + mIsForeground = false; + notifyToBackground(); } - onActivityCeased(activity); } @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) {} + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { - @Override - public void onActivitySaveInstanceState(Activity activity, Bundle outState) {} + } @Override - public void onActivityDestroyed(Activity activity) {} - + public void onActivityDestroyed(Activity activity) { - private void onActivityCeased(Activity activity){ - if (foreground) { - if ((activity == current) && (activity != null && !activity.isChangingConfigurations())){ - foreground = false; - Log.w(TAG, "went background"); - listeners.each(becameBackground); - } else { - Log.i(TAG, "still foreground"); - } - } else { - Log.i(TAG, "still background"); - } } -} \ No newline at end of file + + + + +}