Android 安卓Oreo-作业意图服务正在主线程上运行,导致应用程序冻结几秒钟

Android 安卓Oreo-作业意图服务正在主线程上运行,导致应用程序冻结几秒钟,android,android-jobscheduler,Android,Android Jobscheduler,我试图在后台下载一些文件。之前我使用的是intent服务,我的应用程序在使用intent服务时不会被冻结。但和oreo及以上版本一样,一旦应用程序从后台关闭,Intent服务就会被销毁。我在一个作业服务中做了同样的处理,但它似乎在主线程上运行。对于不应该在主线程上运行的后台处理,我应该怎么做 下面是我所做的作业调度代码: public class Util { // schedule the start of the service every 10 - 30 seconds

我试图在后台下载一些文件。之前我使用的是intent服务,我的应用程序在使用intent服务时不会被冻结。但和oreo及以上版本一样,一旦应用程序从后台关闭,Intent服务就会被销毁。我在一个作业服务中做了同样的处理,但它似乎在主线程上运行。对于不应该在主线程上运行的后台处理,我应该怎么做

下面是我所做的作业调度代码:

public class Util {

    // schedule the start of the service every 10 - 30 seconds
    @TargetApi(Build.VERSION_CODES.M)
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static void scheduleJob(Context context) {
        ComponentName serviceComponent = new ComponentName(context, MyService.class);
        JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
        builder.setMinimumLatency(1 * 1000); // wait at least
        builder.setOverrideDeadline(3 * 1000); // maximum delay
        //builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); // require unmetered network
        //builder.setRequiresDeviceIdle(true); // device should be idle
        //builder.setRequiresCharging(false); // we don't care if the device is charging or not
        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
        jobScheduler.schedule(builder.build());
    }

}



@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MyService extends JobService {
    private static final String TAG = "SyncService";
    public Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
    public SharedPreferences sharedPreferences;
    public ComplexObject complexObject;
    private Context context;
    public static final String NOTIFICATION_CHANNEL_ID = "10001";
    @Override
    public boolean onStartJob(JobParameters params) {
        System.out.println("RUnning this Job.......");
        context = this;
        this.sharedPreferences = context.getSharedPreferences(context.getResources().getString(R.string.shared_preference_key), Context.MODE_PRIVATE);

        //30-40 HTTP call to process the data
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return true;
    }
根据文件:

此服务在应用程序主线程上运行的处理程序上执行每个传入作业。这意味着您必须将执行逻辑卸载到您选择的另一个线程/处理程序/异步任务。不这样做将导致阻止来自JobManager的任何未来回调,特别是onStopJob(android.app.job.JobParameters),这意味着通知您不再满足调度要求

因此,您需要使用AsyncTask或其他形式的异步方法来执行逻辑。不过,您应该使用可取消的功能,因为当调用
onStopJob()
时,您应该停止正在做的任何事情


还记得在逻辑完成后调用
jobFinished()

不确定这是否有帮助,因为它有点旧,但是:
你的标题是,你使用,答案是 引用您使用的类(
JobService
),但如果要使用
JobIntentService
,则其方法在后台线程上运行:

此方法在后台线程上调用,因此您可以在此处执行长阻塞操作


您可以使用JobIntentService作为一个解决方案来下载/上载一些文件,甚至与服务器通信。另一个更好的方法是WorkManager。请注意,IntentService在UI线程上运行,而UI线程是在UI线程上运行的
onHandleContent(Intent-Intent)
。因此,我们应该使用一个单独的线程,或者使用异步任务。但是JobIntentService有一个函数
onHandleWork(@NonNull Intent Intent)
,它是在后台线程上运行的,所以我们只需要对它进行操作。在WorkManager方法中,工作是在Worker的
doWork()
方法中完成的,该函数也在后台线程上运行,因此我们应该在其中编写主代码。我认为JobIntentService和WorkerManager都适合这样做。JobIntentService只运行一次工作,但通过WorkManager,我们可以执行一次工作或定期重复它(周期之间的间隔时间至少为15分钟)

是的,我在这个jobintent服务中没有使用任何回调,我在这里运行一个ThreadPoolExecutor。如何从这些线程获取回调似乎很棘手。使用AsyncTask并在其构造函数中传递回调。如何做到这一点我需要进行30次http请求调用。我能在一个异步任务中调用全部30个http请求吗?是的。。。请你在这方面帮助我,或者在我的示例代码中编写任何有问题的示例