2017-09-11 27 views
3

実行したい定期ジョブが1つあり、EvernoteのAndroidジョブライブラリの助けを借りて実装されています。スケジュールされたジョブはEvernote-AndroidJobで複数回実行されます

私が達成したいのは、マイロケーションを15分更新することです。

問題は、15分ごとにジョブが複数回実行されているようです。

私はOnePlus3デバイスを使用してテストとデバッグから、私は LocationUpdateJob.schedule()が正しいれ、一度だけ呼び出されますが、LocationUpdateJob.onRunJob()が間違っていた、複数回呼び出されますが、一度だけ15分毎に呼び出されるべきであると認められ。

さらに、crashlyticsによると、一部のデバイスからillegalStateExceptionがスローされます。 この例外は、Android 7デバイスでのみ発生します。

ここでクラッシュレポートからクラッシュさ:

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) 

ここでは私のコードです:

Applicataionクラス

@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ののサンプルプロジェクトをフォークし、彼らはまったく同じ手順を実行しますが、私は私が何を見つけ出すことができませんでした異なったやり方。

答えて

6

私は全体の答えを見つけました。 私はこれに答えています、他の誰かが同じ問題に直面している場合は入れてください。

オクラホマので、上記の私のロジックによると、これが起こっていたものです。

1)ユーザーは、ジョブが無限大まで走るOSに予定されている、非常に最初の時間のためのアプリを開きます。

2)ユーザーがもう一度アプリケーションを閉じて開くと、別のジョブがOSでスケジュールされます。

3)ユーザーがアプリを開くと、100個のジョブがスケジュールされ、101番目のジョブがスケジュールされます。アンドロイドはアプリで100個のジョブをスケジュールすることができるため、バージョン)。

これを解決するために私は何をしましたか?

私は次のように見えるために私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)

だから何それが行うことは、仕事があるたびにありますタグ付きでスケジュールされている場合、同じタグを持つ既存のジョブを新しいジョブに置き換えます。したがって、そのタグで実行する予定のジョブは1つだけです。つまり、ジョブのタグは一意になります。

非常に簡潔で良い説明がありますhere、それをお読みください。

関連する問題