You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Android后台服务每小时运行,即使应用被强制关闭?

解决Android网络状态定时检测(应用强关后仍运行)的问题

我明白你的需求:让网络检测服务每小时跑一次,哪怕应用被从最近列表里强制关掉。咱们先看看现有代码的问题,再一步步解决~

现有代码的局限

你当前的NetworkService只是在应用启动时被调用一次,没有定时触发的逻辑;而且普通Service在Android 8.0+的系统中,应用退到后台或被强关后很容易被系统回收,没法保证持续运行。

推荐方案:用WorkManager实现可靠的周期性任务

Google官方推荐使用WorkManager来处理这类需要定时、可靠执行的后台任务,它能自动适配不同Android版本的后台限制,即使应用被关闭、设备重启(可选配置),任务也能继续执行。

步骤1:添加WorkManager依赖

在你的build.gradle(Module level)里添加依赖(根据你的Android Gradle Plugin版本调整,这里用最新稳定版示例):

dependencies {
    implementation "androidx.work:work-runtime:2.8.1"
}

步骤2:创建网络检测Worker类

替代原来的NetworkService,创建一个继承自Worker的类,把网络检测逻辑放在这里:

using System.IO;
using Android.App;
using Android.Content;
using Android.Net;
using AndroidX.Work;

namespace example.Services
{
    public class NetworkCheckWorker : Worker
    {
        public NetworkCheckWorker(Context context, WorkerParameters workerParams) : base(context, workerParams)
        {
        }

        public override Result DoWork()
        {
            // 执行网络检测逻辑
            string filename = "network.txt";
            var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
            var filePath = Path.Combine(documentsPath, filename);

            if (!File.Exists(filePath))
                File.Create(filePath).Close(); // 记得Close,否则会占用文件

            ConnectivityManager connectivityManager = (ConnectivityManager)ApplicationContext.GetSystemService(Context.ConnectivityService);
            bool isOnline = false;

            // 适配Android 10+的Network API(旧的NetworkInfo已被废弃)
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M)
            {
                var network = connectivityManager.ActiveNetwork;
                var capabilities = connectivityManager.GetNetworkCapabilities(network);
                isOnline = capabilities != null && (capabilities.HasTransport(TransportType.Wifi) || capabilities.HasTransport(TransportType.Cellular));
            }
            else
            {
                var networkInfo = connectivityManager.ActiveNetworkInfo;
                isOnline = networkInfo != null && networkInfo.IsConnected;
            }

            File.WriteAllText(filePath, isOnline ? "Connected" : "Not Connected");

            // 返回Result.Success表示任务执行成功,系统会按计划继续下一次
            return Result.InvokeSuccess();
        }
    }
}

注意:这里适配了Android 6.0+的新Network API,因为旧的NetworkInfo已经被废弃了,这样代码兼容性更好。

步骤3:配置并启动周期性任务

在你的MainActivity里,初始化WorkManager的周期性请求,设置每小时执行一次:

using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
using AndroidX.Work;

namespace whitesrecycling.Activities
{
    [Activity(Label = "HomeActivity")]
    public class HomeActivity : Activity
    {
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.Home);
            var toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
            SetActionBar(toolbar);
            ActionBar.Title = "Example";

            // 启动周期性网络检测任务
            StartPeriodicNetworkCheck();
        }

        private void StartPeriodicNetworkCheck()
        {
            // 设置任务约束(可选,比如只在有网络时执行)
            var constraints = new Constraints.Builder()
                .SetRequiredNetworkType(NetworkType.Connected) // 可选,根据需求调整
                .Build();

            // 创建每小时执行一次的周期性请求
            var periodicWorkRequest = new PeriodicWorkRequest.Builder(
                typeof(NetworkCheckWorker), 
                System.TimeSpan.FromHours(1), // 间隔时间
                System.TimeSpan.FromMinutes(10)) // 弹性窗口(允许系统在这个窗口内调整执行时间,优化电池)
                .SetConstraints(constraints)
                .Build();

            // 将任务提交给WorkManager
            WorkManager.GetInstance(ApplicationContext).EnqueueUniquePeriodicWork(
                "NetworkCheckTask", 
                ExistingPeriodicWorkPolicy.Keep, // 如果任务已存在,保留原任务
                periodicWorkRequest);
        }
    }
}

步骤4:移除旧的Service配置

现在你不需要原来的NetworkService了,可以删掉它,同时从AndroidManifest.xml里移除对应的<service>配置。

关键说明

  1. 为什么不用AlarmManager+Service?
    Android 8.0之后,后台Service有严格的限制,应用进入后台后5分钟内Service会被系统停止,AlarmManager的定时任务在后台也可能被延迟或忽略。WorkManager会自动处理这些限制,选择最优的执行方式(比如在API 23+用JobScheduler,API 14-22用AlarmManager+BroadcastReceiver)。

  2. 设备重启后任务是否继续?
    WorkManager默认会在设备重启后恢复任务,不需要额外配置(前提是应用已经被打开过至少一次)。

  3. 任务执行的弹性窗口
    PeriodicWorkRequest的第二个参数是间隔时间,第三个是弹性窗口,系统会在这个窗口内选择合适的时间执行任务,减少对电池的消耗。如果需要严格准时执行,可以用OneTimeWorkRequest结合链式调用,但会增加电池消耗,不推荐。

内容的提问来源于stack exchange,提问作者Gurpreet Bhopal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:03:36