在Foreground服务中运行网络代码后,仍然收到“网络使用率过高(后台)”警告

时间:2019-03-04 14:49:59

标签: android

通过引用Proper way to tackle and resolve "Excessive network usage (background)"

经过几个月的调试,我们现在可以在Foreground服务中运行所有与网络相关的代码。

但是,我们仍然在Android Vital中收到“网络使用率过高(背景)”警告。

enter image description here

执行前台服务代码时,通知UI始终显示在状态栏区域。

enter image description here

“退出”应用程序时,我们使用WorkManager启动前台服务。 WorkManager将在前台服务启动后立即返回。

public class SyncWorker extends Worker {
    @NonNull
    @Override
    public Result doWork() {
        final Intent intent = new Intent(WeNoteApplication.instance(), SyncForegroundIntentService.class);

        ContextCompat.startForegroundService(
                WeNoteApplication.instance(),
                intent
        );

        return Result.success();
    }
}

public class SyncForegroundIntentService extends IntentService {
    private static final String TAG = "com.yocto.wenote.sync.SyncIntentService";

    public SyncForegroundIntentService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {

        final Context context = WeNoteApplication.instance();

        NotificationCompat.Builder builder = new NotificationCompat.Builder(...

        startForeground(SYNC_FOREGROUND_INTENT_SERVICE_ID, builder.build());

        // Perform networking operation within foreground service.

        stopForeground(true);

旁注

我们认为我们没有发送大量数据。如您所见,我们的最新版本处于最低范围(每小时0-5 MB)

enter image description here


您知道为什么我们仍然会收到“网络使用率过高(背景)”的想法吗?显然,我们不再在后台执行任何联网呼叫。

我们利用https://developer.android.com/reference/android/app/Service.html#startForeground(int,%20android.app.Notification)https://developer.android.com/reference/android/content/Context.html#startForegroundService(android.content.Intent)


2 个答案:

答案 0 :(得分:6)

您正在使用Worker来调用ForegroundService。从Worker的文档中:

  

Worker类在运行时由WorkManager实例化,并且   在预先指定的后台线程上调用 doWork()方法(请参见   Configuration.getExecutor())。此方法用于同步   处理您的工作,这意味着一旦您从工作中回来   方法,该工人被认为已经完成,将被销毁。 (...)如果由于任何原因抢占了作品,则不会重复使用相同的Worker实例。这意味着doWork()在每个Worker实例中仅被调用一次。 如果需要重新运行工作单元,则会创建一个新的Worker。

ForegroundService是您置于前台状态的Service,这意味着,如果系统需要CPU或您的应用已关闭,则系统不会终止该进程。这个,也只有那个。 我找不到能证明这一点的Android Vital文档,所以这只是我的怀疑,但是我很肯定是这样:这意味着无论您是否使用ForegroundService Android Vital仍将其视为后台工作。

将应用的移动网络使用率提高到前台的一种正确方法是,使用适当的可见性设置集(如您提供的链接所述)致电DownloadManager。请告诉我是否有帮助-否则,我们将尝试其他尝试。顺便说一句,您是否能够将统计信息缩小到特定的API版本? (在9.0和8.0中有一些后台线程更改,因此这也可能是一个线索)

答案 1 :(得分:2)

如果您正在这样做:

  

“退出”应用程序时,我们使用WorkManager启动前台服务。启动前台服务后,WorkManager将立即返回。

那么从技术上讲,每次用户关闭应用程序时,您都在计划可能受到网络限制的工作人员。

摘自“过度使用后台网络”文档link

  

当应用程序在后台连接到移动网络时,该应用程序将唤醒CPU并打开无线电。反复这样做会耗尽设备的电池电量

因此,即使您没有发送50MB /电池电量的0.10%的阈值数据,您也会收到此警告,因为从技术上讲,您的应用在后台唤醒了CPU很多(用于网络ping)。 / p>


尽管我不确定这是否是问题,但是您可以做的是,因为甚至工人文档指南都说:

  

WorkManager用于可延迟的任务-即不需要立即运行-并且即使应用程序退出或设备重新启动也需要可靠地运行

您可以尝试以下方法:

  1. 用户关闭应用程序后立即安排前台服务,而不是安排工作人员,而是在onHandleIntent内部检查用户是否在线(具有连接且对于7以上的设备而言)以及流畅的互联网连接。)

  2. 您可以尝试安排工作人员定期运行,假设根据您的业务方面的需求每隔几个小时运行一次,如果这不是您希望备份数据的方式,则可能会出现问题,但是它可以满足工人的真正目的是推迟任务,而不是立即执行的任务。

  3. 不确定这一点,从未尝试过,但是从理论上看是有效的,您可以使用REPLACE模式的Unique Work来替换工作程序,并且初始延迟为30分钟,这是一种黑客行为,但这将使您的工作程序运行时间延迟30分钟,与此同时,如果用户再次打开和关闭该应用程序,它将用新的工作程序替换旧的工作程序。该解决方案也有其自身的缺点,例如,如果用户不断使用该应用程序,则有时将无法安排任务。但这将减少工人跑的总次数。


最后,您使用的架构是有效的,有关使用FG服务和工作人员进行调度的全部内容,只是您经常这样做。 Source