publicstatic@NonNull WorkManagerImpl getInstance(@NonNull Context context) { synchronized (sLock) { WorkManagerImplinstance= getInstance(); if (instance == null) { ContextappContext= context.getApplicationContext(); if (appContext instanceof Configuration.Provider) { initialize( appContext, ((Configuration.Provider) appContext).getWorkManagerConfiguration()); instance = getInstance(appContext); } else { thrownewIllegalStateException("WorkManager is not initialized properly. You " + "have explicitly disabled WorkManagerInitializer in your manifest, " + "have not manually called WorkManager#initialize at this point, and " + "your Application does not implement Configuration.Provider."); } }
public Operation enqueue( @NonNull List<? extends WorkRequest> workRequests) {
// This error is not being propagated as part of the Operation, as we want the // app to crash during development. Having no workRequests is always a developer error. if (workRequests.isEmpty()) { thrownewIllegalArgumentException( "enqueue needs at least one WorkRequest."); } returnnewWorkContinuationImpl(this, workRequests).enqueue(); }
调用enqueue方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
public@NonNull Operation enqueue() { // Only enqueue if not already enqueued. if (!mEnqueued) { // The runnable walks the hierarchy of the continuations // and marks them enqueued using the markEnqueued() method, parent first. EnqueueRunnablerunnable=newEnqueueRunnable(this); mWorkManagerImpl.getWorkTaskExecutor().executeOnBackgroundThread(runnable); mOperation = runnable.getOperation(); } else { Logger.get().warning(TAG, String.format("Already enqueued work ids (%s)", TextUtils.join(", ", mIds))); } return mOperation; }
// Mark all the WorkSpecs as scheduled. // Calls to Scheduler#schedule() could potentially result in more schedules // on a separate thread. Therefore, this needs to be done first. for (WorkSpec workSpec : eligibleWorkSpecs) { workSpecDao.markWorkSpecScheduled(workSpec.id, now); } } workDatabase.setTransactionSuccessful(); } finally { workDatabase.endTransaction(); }
if (eligibleWorkSpecs != null && eligibleWorkSpecs.size() > 0) { WorkSpec[] eligibleWorkSpecsArray = eligibleWorkSpecs.toArray(newWorkSpec[0]); // Delegate to the underlying scheduler. for (Scheduler scheduler : schedulers) { scheduler.schedule(eligibleWorkSpecsArray); } } }
publicvoidschedule(@NonNull WorkSpec... workSpecs) { if (mIsMainProcess == null) { // The default process name is the package name. mIsMainProcess = TextUtils.equals(mContext.getPackageName(), getProcessName()); }
if (!mIsMainProcess) { Logger.get().info(TAG, "Ignoring schedule request in non-main process"); return; }
registerExecutionListenerIfNeeded();
// Keep track of the list of new WorkSpecs whose constraints need to be tracked. // Add them to the known list of constrained WorkSpecs and call replace() on // WorkConstraintsTracker. That way we only need to synchronize on the part where we // are updating mConstrainedWorkSpecs. List<WorkSpec> constrainedWorkSpecs = newArrayList<>(); List<String> constrainedWorkSpecIds = newArrayList<>(); for (WorkSpec workSpec : workSpecs) { if (workSpec.state == WorkInfo.State.ENQUEUED && !workSpec.isPeriodic() && workSpec.initialDelay == 0L && !workSpec.isBackedOff()) { if (workSpec.hasConstraints()) { if (SDK_INT >= 23 && workSpec.constraints.requiresDeviceIdle()) { // Ignore requests that have an idle mode constraint. Logger.get().debug(TAG, String.format("Ignoring WorkSpec %s, Requires device idle.", workSpec)); } elseif (SDK_INT >= 24 && workSpec.constraints.hasContentUriTriggers()) { // Ignore requests that have content uri triggers. Logger.get().debug(TAG, String.format("Ignoring WorkSpec %s, Requires ContentUri triggers.", workSpec)); } else { constrainedWorkSpecs.add(workSpec); constrainedWorkSpecIds.add(workSpec.id); } } else { Logger.get().debug(TAG, String.format("Starting work for %s", workSpec.id)); mWorkManagerImpl.startWork(workSpec.id); } } }
// onExecuted() which is called on the main thread also modifies the list of mConstrained // WorkSpecs. Therefore we need to lock here. synchronized (mLock) { if (!constrainedWorkSpecs.isEmpty()) { Logger.get().debug(TAG, String.format("Starting tracking for [%s]", TextUtils.join(",", constrainedWorkSpecIds))); mConstrainedWorkSpecs.addAll(constrainedWorkSpecs); mWorkConstraintsTracker.replace(mConstrainedWorkSpecs); } } }
WorkerWrapper workWrapper; synchronized (mLock) { // Work may get triggered multiple times if they have passing constraints // and new work with those constraints are added. if (mEnqueuedWorkMap.containsKey(id)) { Logger.get().debug( TAG, String.format("Work %s is already enqueued for processing", id)); returnfalse; }