Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 65 additions & 127 deletions Foredroid/src/main/java/com/sjl/foreground/Foreground.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<WeakReference<Listener>> mListenerList;
private boolean mIsForeground;
private Stack<Activity> mActivityStack;

private interface Callback {
public void invoke(Listener listener);
private Foreground(){
mListenerList = new LinkedList<WeakReference<Listener>>();
mActivityStack = new Stack<Activity>();
}

private static class Listeners {
private List<WeakReference<Listener>> listeners = new CopyOnWriteArrayList<>();

public Binding add(Listener listener){
final WeakReference<Listener> 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<WeakReference<Listener>> it = listeners.iterator(); it.hasNext();) {
try {
WeakReference<Listener> 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<Listener> 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<Listener> 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<Listener> listenerWeakRef = new WeakReference<Listener>(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<Listener> 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<Activity> 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");
}
}
}




}