本文介绍了预定作业在Evernote中执行多次-AndroidJob的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一份要运行的定期作业,它是在Evernote的Android Job库的帮助下实现的.

I have one periodic job I want to run and it is implemented with the help of Evernote's Android Job library.

我希望实现的是每15分钟更新一次MyLocation.

What I wish to achieve is to updateMyLocation ever 15 mins.

问题在于,每15分钟,该作业似乎执行了多次.

The problem is that every 15 mins, the job seems to be executing multiple times.

我使用OnePlus3设备进行了测试,并从调试中观察到 LocationUpdateJob.schedule()仅被调用一次,这是正确的,但是 LocationUpdateJob.onRunJob()被多次调用,这是不正确的,但只能被调用一次每15分钟一次.

I tested using a OnePlus3 device and from debugging, I observed that theLocationUpdateJob.schedule() is called only once, which is correct, but the LocationUpdateJob.onRunJob() gets called multiple times, which is incorrect, but should only be called once every 15 mins.

另外,据crashlytics称,从某些设备抛出了非法状态异常.此特定例外仅在Android 7设备上发生.

Additionally, illegalStateExceptions are thrown from some devices, according to crashlytics.This particular exception only happens on Android 7 devices.

这是崩溃报告中的崩溃:

Here is the crash from crash report:

    Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.myapp/MainActivity}: java.lang.IllegalStateException: Apps may not schedule more than 100 distinct jobs
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2947)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3008)
       at android.app.ActivityThread.-wrap14(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6688)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Caused by java.lang.IllegalStateException: Apps may not schedule more than 100 distinct jobs
       at android.os.Parcel.readException(Parcel.java:1701)
       at android.os.Parcel.readException(Parcel.java:1646)
       at android.app.job.IJobScheduler$Stub$Proxy.schedule(IJobScheduler.java:158)
       at android.app.JobSchedulerImpl.schedule(JobSchedulerImpl.java:42)
       at com.evernote.android.job.v21.JobProxy21.schedule(SourceFile:198)
       at com.evernote.android.job.v21.JobProxy21.plantPeriodic(SourceFile:92)
       at com.evernote.android.job.JobManager.scheduleWithApi(SourceFile:282)
       at com.evernote.android.job.JobManager.schedule(SourceFile:240)
       at com.evernote.android.job.JobRequest.schedule(SourceFile:366)
       at com.mydomain.myapp.service.locationUpdate.LocationUpdateJob.schedule(SourceFile:33)
       at com.mydomain.myapp.activities.HubActivity.onLoginSuccess(SourceFile:173)
       at com.mydomain.myapp.activities.HubActivity.onCreate(SourceFile:115)
       at android.app.Activity.performCreate(Activity.java:6912)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2900)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3008)
       at android.app.ActivityThread.-wrap14(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1650)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6688)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

这是我的代码:

应用程序类

@Override
public void onCreate() {
 //init things....
 JobManager
           .create(this)
           .addJobCreator(new LocationUpdateJobCreator());
 }

LocationUpdateJobCreator

public class LocationUpdateJobCreator implements JobCreator {

    @Override
    public Job create(String s) {
        switch (s) {
            case LocationUpdateJob.TAG:
                return new LocationUpdateJob();
            default:
                return null;
        }
    }
}

MainActivity:

private void onLogin() {
   // do other things...
   LocationUpdateJob.schedule();
 }

LocationUpdateJob

public class LocationUpdateJob extends Job {

    public static final String TAG = "LocationUpdateJob";
    private static int jobId = -1;


    public static void schedule() {
        final long INTERVAL = 900000L;
        final long FLEX = 300000L;
        jobId = new JobRequest
                .Builder(LocationUpdateJob.TAG)
                .setPeriodic(INTERVAL, FLEX)
                .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
                .build()
                .schedule();
    }


    public static void stop() {
        JobManager
                .instance()
                .cancel(jobId);
    }


    @NonNull
    @Override
    protected Result onRunJob(Params params) {
        updateLocation();
        return Result.SUCCESS;
    }
}

我分叉了Evernote的示例项目,但是它们执行的步骤完全相同,但是我无法弄清楚我在做什么.

I forked the Evernote's sample project, but they do the exact same steps, but I couldn't figure out what I am doing differently.

推荐答案

我找到了整个问题的答案.我正在回答这个问题,以防其他人遇到同样的问题.

I found the answer to the whole thing.I am answering this, incase anyone else faces the same issue.

好,所以根据我上面的逻辑,这就是发生的事情:

Ok, so according to my logic above, this is what was happening :

1)用户第一次打开该应用程序,在操作系统中计划了一个作业,该作业一直运行到无穷远.

1) User opens the app for very first time, a job is scheduled in the OS, which runs till infinity.

2)用户关闭并再次打开应用程序,在操作系统中计划了另一个作业.

2) User closes and opens the app again, another job is scheduled in the OS.

3)到用户第101次打开应用程序时,现在已调度了100个作业,并且该应用程序将调度第101个作业,这引发了异常,因为android仅允许应用程序调度100个作业(在较新的OS版本中).

3) By the 101th time user opens the app, there are now 100 jobs scheduled and the app goes to schedule the 101th job, which throws an exception, because android only allows an app to schedule 100 jobs(in newer OS versions).

那么,我该怎么解决呢?

So, what did I do to solve this ?

我将 schedule()修改为如下所示:

public static void schedule() {
     final long INTERVAL = 900000L;
     final long FLEX = 300000L;
     jobId = new JobRequest
                    .Builder(LocationUpdateJob.TAG)
                    .setPeriodic(INTERVAL, 300000L)
                    .setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
                    .setPersisted(true)
                    .setUpdateCurrent(true)
                    .build()
                    .schedule();
}

这里与我计划的旧方法有何不同: .setUpdateCurrent(true)

What is different here, from the old way I scheduled is : .setUpdateCurrent(true)

所以这样做是,每次使用标签计划作业时,它都会用新作业替换具有相同标签的任何现有作业,因此仅计划使用该标签执行一个作业,即该作业的标签是唯一的.

So what that does is, every time a job is scheduled with a tag, it replaces any existing jobs with the same tag, with the new job, therefore only one job is scheduled to execute with that tag, ie,the job's Tag is made unique.

此处,有一个非常简短且很好的解释,请仔细阅读.

There is a very brief and good explanation here, please read it.

这篇关于预定作业在Evernote中执行多次-AndroidJob的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 17:54