开发者社区 问答 正文

为什么即使未满足职位信息的要求,后台服务仍能继续运行?

我试图根据互联网连接(蜂窝)执行后台任务,所以我在jobinfo中设置了RequiredNetworkType(JobInfo.NETWORK_TYPE_CELLULAR),我期望后台作业服务在蜂窝互联网连接打开之前不会运行,但是即使关闭Internet连接,服务也会运行。

这是我的代码(jobinfo)

ComponentName componentName=new ComponentName(this,MyService.class);
JobInfo info=new JobInfo.Builder(0,componentName)
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_CELLULAR)
    .setPersisted(true)
    .setPeriodic(15000)
    .build();

JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
int resultcode=scheduler.schedule(info);
if (resultcode==JobScheduler.RESULT_SUCCESS){
Log.d(TAG,"job scheduled");
}else{
Log.d(TAG,"failed");
}

我的工作服务

private static final String TAG="MyService";
boolean jobcancelled=false;



@Override
public boolean onStartJob(JobParameters params) {
backgroundService(params);
return true;
}

private void backgroundService(final JobParameters params) {

new Thread(new Runnable() {
@Override
public void run() {
    if (jobcancelled) {
        return;
    }

        Notification.Builder notification = new Notification.Builder(MyService.this)
            // this Builder class is deprecated
                .setDefaults(NotificationCompat.DEFAULT_SOUND)
                .setPriority(Notification.PRIORITY_MAX)
                .setLights(0xff00ff00, 300, 100)
                .setSmallIcon(R.drawable.ic_launcher_background)
                .setContentTitle("My notification")
                .setContentText("Hello Peter");


            NotificationManagerCompat manager =   NotificationManagerCompat.from(MyService.this);
        manager.notify(1, notification.build());


    jobFinished(params,false);
}
}).start();
}
@Override
public boolean onStopJob(JobParameters params) {
Log.d(TAG,"job cancelled before completion");
jobcancelled=true;
return true;
}

展开
收起
Puppet 2019-12-05 12:48:42 342 分享 版权
阿里云 AI 助理回答

根据您的描述,您希望在设备仅连接到蜂窝数据网络时才执行后台任务。然而,即使在没有互联网连接的情况下,任务似乎仍然在运行。这可能是由于几个原因造成的:

  1. JobScheduler的Periodic特性:您设置了setPeriodic(15000),这意味着系统会尝试按照15秒的周期重新安排作业。即使当前不符合网络条件,系统仍可能会尝试调度作业,并在将来满足条件时执行。对于需要特定网络条件的任务,建议使用一次性作业(setOverrideDeadline()setMinimumLatency())而不是周期性作业,以更精确地控制执行时机。

  2. 网络状态判断逻辑:Android系统的JobScheduler可能对网络类型的检查存在一定的宽容度或者延迟。即使您指定了JobInfo.NETWORK_TYPE_CELLULAR,在某些情况下,如果系统认为短时间内网络可能会恢复,它仍可能尝试执行作业。

  3. 调试和测试环境:在某些模拟器或测试环境下,网络状态可能不如真实设备准确,导致预期行为与实际表现不一致。

解决方案

  • 改为使用一次性作业:考虑将周期性作业改为一次性作业,并在每次作业完成时根据需要重新调度下一次作业。这样可以提供更多的控制权,确保只有在满足所有条件时才执行作业。
// 例如,使用setOverrideDeadline来设置一个执行的最晚时间点
info = new JobInfo.Builder(0, componentName)
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_CELLULAR)
    .setPersisted(true)
    // 设置一个执行的最后期限,比如30分钟内必须执行
    .setOverrideDeadline(30 * 60 * 1000) 
    .build();
  • 检查网络状态:在onStartJob()方法中添加额外的网络状态检查,确保在执行任务前确实连接到了所需的网络类型。虽然理论上JobScheduler应该处理这个,但额外的检查可以作为保险措施。
@Override
public boolean onStartJob(JobParameters params) {
    ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork != null && activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
        // 确保是蜂窝网络
        backgroundService(params);
    } else {
        Log.d(TAG, "Not on cellular network, job not executed.");
        // 可能需要在这里调用jobFinished并返回false,或者根据需求处理
    }
    return true; // 或者根据你的处理逻辑调整这里
}
  • 测试环境验证:确保在真实的设备上进行测试,特别是当涉及到网络状态检测时,模拟器的行为可能与物理设备不同。

通过上述调整,您可以更好地控制作业在特定网络条件下执行的时机,从而解决当前遇到的问题。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答地址: