我们如何检测被用户或系统杀死的Android应用程序?

时间:2015-10-06 08:06:15

标签: android singleton heap-memory

是否有可能检测到用户已杀死或退出的Android应用程序?

我尝试在Application类中使用 ActivityLifecycleCallbacks 来检测它,方法是通过在 onActivityCreated 中添加int参数并增加它,如下所示;但它不起作用。
我认为我的应用程序中的 Android服务使得这个全局计数器变量(在单例类中定义)虽然应用程序已被杀死但未被杀死。
它仅在应用程序首次启动时首次启动为零,然后每个应用程序重新启动它具有最后一次应用程序被杀死时的最后一个值,并且永远不再具有零值。

另一个问题是当使用Android服务的应用程序被杀时,我们如何将全局值释放到其初始值?

具有全局活动计数器的Singleton类

public class SingletonClass {

    public int created_activity_number;

    private static volatile SingletonClass instance = null;

    private SingletonClass() {

    }

    public static SingletonClass getInstance() {
        if (instance == null) {
            synchronized (SingletonClass.class) {
                // Double check
                if (instance == null) {
                    instance = new SingletonClass();
                }
            }
        }
        return instance;
    }
}   

ActivityLifecycleCallbacks类

 public class MyLifecycleHandler implements Application.ActivityLifecycleCallbacks {

            private static int created;

            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                SingletonClass.getInstance().created_activity_number++;
            }

            @Override
            public void onActivityStarted(Activity activity) {

            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {

            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        }

在我使用以下条件的任何活动中,检查活动是否是应用程序启动时首次创建的活动。

// Enter this condition only one time no mattter how many times the application killed by the user end starts again.
if (SingletonClass.getInstance().created_activity_number == 1) {
            // Yes, it is the first created activiy 
}

1 个答案:

答案 0 :(得分:0)

我有同样的问题,请使用此类

public class Foreground implements Application.ActivityLifecycleCallbacks {

public static final long CHECK_DELAY = 500;
public static final String TAG = Foreground.class.getName();

public interface Listener {

    public void onBecameForeground();

    public void onBecameBackground();

}

private static Foreground instance;

private boolean foreground = false, paused = true;
private Handler handler = new Handler();
private List<Listener> listeners = new CopyOnWriteArrayList<Listener>();
private Runnable check;

/**
 * Its not strictly necessary to use this method - _usually_ invoking
 * get with a Context gives us a path to retrieve the Application and
 * initialise, but sometimes (e.g. in test harness) the ApplicationContext
 * is != the Application, and the docs make no guarantees.
 *
 * @param application
 * @return an initialised Foreground instance
 */
public static Foreground init(Application application){
    if (instance == null) {
        instance = new Foreground();
        application.registerActivityLifecycleCallbacks(instance);
    }
    return instance;
}

public static Foreground get(Application application){
    if (instance == null) {
        init(application);
    }
    return instance;
}

public static Foreground 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 Foreground 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 addListenerUnique(Listener listener){
    if(!listeners.contains(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.i(TAG, "went foreground");
        for (Listener l : listeners) {
            try {
                l.onBecameForeground();
            } catch (Exception exc) {
                Log.e(TAG, "Listener threw exception!", exc);
            }
        }
    } else {
        Log.i(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;
                Log.i(TAG, "went background");
                for (Listener l : listeners) {
                    try {
                        l.onBecameBackground();
                    } catch (Exception exc) {
                        Log.e(TAG, "Listener threw exception!", exc);
                    }
                }
            } else {
                Log.i(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) {}
}

在你的应用程序类

中初始化它
Foreground.init(this);

然后使用监听器来了解app状态