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

Android使用Volley在后台执行HTTP轮询请求出现超时错误如何解决

安卓后台Volley请求超时解决方案

问题根因

退后台后请求超时是安卓系统对后台服务的限制导致的:

  • 安卓8.0(API 26)及以上版本,普通后台服务在应用退后台后几分钟内就会被系统冻结,限制网络访问权限,导致请求无法发出触发超时
  • 各大厂商定制的省电策略、电池优化规则会主动切断后台应用的网络连接,降低功耗
  • 未配置Volley的重试策略,默认超时时间短、重试次数少,后台网络波动时更容易触发超时
  • 你当前代码里的URL和广播Action使用的是中文双引号,首先需要替换为英文双引号,否则会出现编译错误

修复步骤

1. 将普通Service改为前台服务

前台服务优先级更高,系统不会轻易冻结,需要做如下修改:

第一步:AndroidManifest.xml新增权限

<!-- 前台服务权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- 安卓13及以上需要通知权限,用来显示前台服务通知 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<!-- 如需申请忽略电池优化新增该权限 -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

第二步:修改ScheduledService的onStartCommand方法,启动前台服务

在startTimer()执行前添加通知代码:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "On Start Command called");
    String action = intent.getAction();
    if (action.equals("START_TIMER")) {
        // 安卓8.0及以上需要创建通知渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("SCHEDULED_SERVICE_CHANNEL", "轮询服务", NotificationManager.IMPORTANCE_LOW);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }
        // 构建前台服务通知
        Notification notification = new NotificationCompat.Builder(this, "SCHEDULED_SERVICE_CHANNEL")
                .setContentTitle("后台轮询中")
                .setContentText("应用正在后台同步数据")
                .setSmallIcon(R.mipmap.ic_launcher) // 替换为你的应用图标
                .build();
        // 启动前台服务,ID不能为0
        startForeground(1001, notification);
        
        String urlInput = "https://jsonplaceholder.typicode.com/todos/1";
        String field = "title";
        Log.d(TAG, "Start Timer now******");
        startTimer(urlInput, field);
    } else if (action.equals("STOP_TIMER")) {
        // 停止前台服务
        stopForeground(true);
        stopTimer();
        stopSelf();
    }
    return START_NOT_STICKY;
}

2. 配置Volley重试策略

给JsonObjectRequest添加超时配置,避免网络波动导致超时:

jsonObjectRequest.setShouldCache(false);
// 新增重试策略:超时10秒,最多重试2次
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
        10000,
        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
));
requestQueue.add(jsonObjectRequest);

3. 引导用户关闭电池优化

可以在应用启动时弹窗引导用户将应用加入电池优化白名单,避免厂商省电策略切断网络:

// 检查是否已经忽略电池优化
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    PowerManager powerManager = getSystemService(PowerManager.class);
    if (!powerManager.isIgnoringBatteryOptimizations(getPackageName())) {
        // 跳转到设置页面让用户开启
        Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivity(intent);
    }
}

注意:如果应用要上架Google Play,需要确保后台轮询是应用核心功能,否则可能因为申请该权限被驳回。

4. 替换Timer实现

Timer是Java原生的定时工具,在后台线程挂起时容易出现偏差,推荐使用Handler + postDelayed实现定时任务,适配安卓的线程调度规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:15:03