diff --git a/CHANGELOG.md b/CHANGELOG.md index a9340f5d..b55ac437 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.3.0-alpha02 +* Initialize the job storage on a background thread, see $471 + ## 1.3.0-alpha01 (2018-05-28) * Implement an API that uses the `WorkManager` for scheduling work items diff --git a/demo/src/main/java/com/evernote/android/job/demo/App.java b/demo/src/main/java/com/evernote/android/job/demo/App.java index 5e32ae91..4d9d05a8 100644 --- a/demo/src/main/java/com/evernote/android/job/demo/App.java +++ b/demo/src/main/java/com/evernote/android/job/demo/App.java @@ -1,6 +1,7 @@ package com.evernote.android.job.demo; import android.app.Application; +import android.os.StrictMode; import com.evernote.android.job.JobManager; import com.facebook.stetho.Stetho; @@ -15,6 +16,22 @@ public void onCreate() { super.onCreate(); Stetho.initializeWithDefaults(this); + if (BuildConfig.DEBUG) { + StrictMode.setThreadPolicy( + new StrictMode.ThreadPolicy.Builder() + .detectAll() + .penaltyLog() + .penaltyDeath() + .build()); + + StrictMode.setVmPolicy( + new StrictMode.VmPolicy.Builder() + .detectAll() + .penaltyLog() + .penaltyDeath() + .build()); + } + JobManager.create(this).addJobCreator(new DemoJobCreator()); } } diff --git a/library/src/main/java/com/evernote/android/job/JobManager.java b/library/src/main/java/com/evernote/android/job/JobManager.java index 30998ed3..e30ee033 100644 --- a/library/src/main/java/com/evernote/android/job/JobManager.java +++ b/library/src/main/java/com/evernote/android/job/JobManager.java @@ -38,6 +38,8 @@ import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; /** * Entry point for scheduling jobs. Depending on the platform and SDK version it uses different APIs @@ -136,18 +138,28 @@ public static JobManager instance() { private final Context mContext; private final JobCreatorHolder mJobCreatorHolder; - private final JobStorage mJobStorage; private final JobExecutor mJobExecutor; - private JobManager(Context context) { + private JobStorage mJobStorage; + private final CountDownLatch mJobStorageLatch; + + private JobManager(final Context context) { mContext = context; mJobCreatorHolder = new JobCreatorHolder(); - mJobStorage = new JobStorage(context); mJobExecutor = new JobExecutor(); if (!JobConfig.isSkipJobReschedule()) { JobRescheduleService.startService(mContext); } + + mJobStorageLatch = new CountDownLatch(1); + JobConfig.getExecutorService().execute(new Runnable() { + @Override + public void run() { + mJobStorage = new JobStorage(context); + mJobStorageLatch.countDown(); + } + }); } /** @@ -181,7 +193,7 @@ public synchronized void schedule(@NonNull JobRequest request) { request.setScheduledAt(JobConfig.getClock().currentTimeMillis()); request.setFlexSupport(flexSupport); - mJobStorage.put(request); + getJobStorage().put(request); try { scheduleWithApi(request, jobApi, periodic, flexSupport); @@ -191,7 +203,7 @@ public synchronized void schedule(@NonNull JobRequest request) { } catch (Exception e) { // if something fails, don't keep the job in the database, it would be rescheduled later - mJobStorage.remove(request); + getJobStorage().remove(request); throw e; } @@ -204,7 +216,7 @@ public synchronized void schedule(@NonNull JobRequest request) { } catch (Exception e) { if (jobApi == JobApi.V_14 || jobApi == JobApi.V_19) { // at this stage we cannot do anything - mJobStorage.remove(request); + getJobStorage().remove(request); throw e; } else { jobApi = JobApi.V_19.isSupported(mContext) ? JobApi.V_19 : JobApi.V_14; // try one last time @@ -215,7 +227,7 @@ public synchronized void schedule(@NonNull JobRequest request) { scheduleWithApi(request, jobApi, periodic, flexSupport); } catch (Exception e) { // if something fails, don't keep the job in the database, it would be rescheduled later - mJobStorage.remove(request); + getJobStorage().remove(request); throw e; } } @@ -248,7 +260,7 @@ public JobRequest getJobRequest(int jobId) { } /*package*/ JobRequest getJobRequest(int jobId, boolean includeStarted) { - JobRequest jobRequest = mJobStorage.get(jobId); + JobRequest jobRequest = getJobStorage().get(jobId); if (!includeStarted && jobRequest != null && jobRequest.isStarted()) { return null; } else { @@ -278,14 +290,14 @@ public Set getAllJobRequestsForTag(@NonNull String tag) { } /*package*/ Set getAllJobRequests(@Nullable String tag, boolean includeStarted, boolean cleanUpTransient) { - Set requests = mJobStorage.getAllJobRequests(tag, includeStarted); + Set requests = getJobStorage().getAllJobRequests(tag, includeStarted); if (cleanUpTransient) { Iterator iterator = requests.iterator(); while (iterator.hasNext()) { JobRequest request = iterator.next(); if (request.isTransient() && !request.getJobApi().getProxy(mContext).isPlatformJobScheduled(request)) { - mJobStorage.remove(request); + getJobStorage().remove(request); iterator.remove(); } } @@ -444,6 +456,14 @@ public void removeJobCreator(JobCreator jobCreator) { } /*package*/ JobStorage getJobStorage() { + if (mJobStorage == null) { + try { + mJobStorageLatch.await(3, TimeUnit.SECONDS); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + return mJobStorage; }