简体   繁体   English

检查我的应用程序是否在后台运行

[英]check if my app is running in the background

this question has been asked like a hundred times but all i could fine have the same answer using 这个问题已经被问了一百遍了,但是我所能使用的答案都相同

getRunningAppProcesses()

which doesn't work properly on Lollipop 在棒棒糖上无法正常工作

so it there a completely reliable way to know if my app is alive in the background? 因此,这是一种完全可靠的方式来知道我的应用程序是否在后台运行吗?

Thank you 谢谢

EDIT: 编辑:

This's what i use to check if the app in the foreground: 这就是我用来检查应用程序是否在前台的内容:

the preferences used: 使用的首选项:

    public static void setStartingActivity(Context context, boolean isStartingActivity) {
        PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean("isStartingActivity", isStartingActivity).apply();
    }

    public static boolean isStartingActivity(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("isStartingActivity", false);
    }

    public static void setAppRunningInForeground(Context context, boolean isRunning) {
        PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean("AppIsRunningInForeground", isRunning).apply();
    }

    public static boolean isAppRunningForeground(Context context) {
        return PreferenceManager.getDefaultSharedPreferences(context).getBoolean("AppIsRunningInForeground", false);
    }

starting the activity: 开始活动:

Utility.PreferencesManager.setStartingActivity(getApplicationContext(), true);
startActivity(new Intent(getApplicationContext(), MainActivity.class));

the onStop and onStart implementation: onStop和onStart实现:

@Override
protected void onStart() {
    super.onStart();
    Log.e("Debugging", "MainActivity onStart");
    Utility.PreferencesManager.setAppRunningInForeground(getApplicationContext(), true);
}

@Override
protected void onStop() {
    super.onStop();
    Log.e("Debugging", "MainActivity onStop");

    if (!Utility.PreferencesManager.isStartingActivity(getApplicationContext()))
        Utility.PreferencesManager.setAppRunningInForeground(getApplicationContext(), false);
    else
        Utility.PreferencesManager.setStartingActivity(getApplicationContext(), false);
}

Blocking syncs when the UI is around is not going to solve your problem, simply because the user may return to your UI while you are in the middle of a sync. 仅当用户界面处于同步状态时,阻止同步不会解决您的问题,这仅仅是因为用户可能会在同步过程中返回您的用户界面。 You need to be able to handle this situation. 您需要能够处理这种情况。

Avoiding syncs when the user has recently been in your UI, for some short value of "recently", may help reduce the odds that the user will return to your UI while the app is syncing. 避免在用户最近进入您的用户界面时进行同步(对于“最近”来说是一个较短的值),可以帮助减少用户在应用同步时返回您的用户界面的几率。

Based on your comments, let's assume that your app consists of 1+ activities plus your sync adapter. 根据您的评论,我们假设您的应用包含1个以上的活动以及同步适配器。 When your sync adapter runs, you want to determine if the user has been in the UI recently for this process. 当您的同步适配器运行时,您想确定该用户最近是否在用户界面中。

There are three possibilities: 有三种可能性:

  1. The UI is in the foreground when the sync adapter runs 同步适配器运行时,UI处于前台

  2. The UI is in the background when the sync adapter runs 同步适配器运行时,UI处于后台

  3. There is no UI, as the last process that had your UI had been terminated, and your sync adapter is running in a fresh process with no UI bits 没有用户界面,因为上一个终止用户界面的进程已经完成,并且同步适配器在没有用户界面位的全新进程中运行

Off the cuff, to handle that, I would have a custom Application , with two boolean fields: 为了解决这个问题,我将使用一个带有两个boolean字段的自定义Application

  • areActivitiesCreated , which will be true if this process ever created an activity, false by default areActivitiesCreated ,这将是true ,如果这个过程中所创造的活动, false默认

  • isInBackground , which will be true if the app is in the background, false otherwise isInBackground ,这将是true ,如果应用程序是在后台, false否则

I would have the Application call registerActivityLifecycleCallbacks() , and set areActivitiesCreated to true in onActivityCreated of the callback. 我将让Application 调用registerActivityLifecycleCallbacks() ,并在回调的onActivityCreated中将areActivitiesCreated设置为true

I would have the Application override onTrimMemory() , and update isInBackground based on the passed-in trim level, setting it to false if the trim level is one of the TRIM_MEMORY_RUNNING_* values, or true otherwise. 我将让Application覆盖onTrimMemory() ,并根据传入的修剪级别更新isInBackground ,如果修剪级别为TRIM_MEMORY_RUNNING_*值之一,则将其设置为false否则将其设置为true

Then, your sync adapter would go ahead and do its work if either areActivitiesCreated is false (meaning that you have no UI) or if isInBackground is true (meaning that you are not in the foreground). 然后,如果areActivitiesCreatedfalse (表示您没有UI)或isInBackgroundtrue (表示您不在前台),则同步适配器将继续工作。

This avoids the need to add code to all the activities to track this condition. 这避免了向所有活动添加代码以跟踪此情况的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM