JobIntentService 用于处理已排队等待作业 / 服务的工作的助手
Android O 之后会自动用 JobScheduler,之前用的
- 由于 Android O 的后台限制,创建后台服务需要使用 JobScheduler 来由系统进行调度任务的执行,而使用 JobService 的方式比较繁琐,8.0 及以上提供了 JobIntentService 帮助开发者更方便的将任务交给 JobScheduler 调度,其本质是 Service 后台任务在他的 OnhandleWork() 中进行,子类重写该方法即可
static WorkEnqueuer getWorkEnqueuer(Context context, ComponentName cn, boolean hasJobId,
int jobId) {
WorkEnqueuer we = sClassWorkEnqueuer.get(cn);
if (we == null) {
if (Build.VERSION.SDK_INT >= 26) {
if (!hasJobId) {
throw new IllegalArgumentException("Can't be here without a job id");
}
we = new JobWorkEnqueuer(context, cn, jobId);
} else {
we = new CompatWorkEnqueuer(context, cn);
}
sClassWorkEnqueuer.put(cn, we);
}
return we;
}
这里区分了任务队列的不同,看看 Android O 之前的处理——CompatWorkEnqueuer 里的入队方法:
@Override
void enqueueWork(Intent work) {
Intent intent = new Intent(work);
intent.setComponent(mComponentName);
if (DEBUG) Log.d(TAG, "Starting service for work: " + work);
if (mContext.startService(intent) != null) {
synchronized (this) {
if (!mLaunchingService) {
mLaunchingService = true;
if (!mServiceProcessing) {
// If the service is not already holding the wake lock for
// itself, acquire it now to keep the system running until
// we get this work dispatched. We use a timeout here to
// protect against whatever problem may cause it to not get
// the work.
mLaunchWakeLock.acquire(60 * 1000);
}
}
}
}
}
注意这里使用了 PowerManager.WakeLock 的 PARTIAL_ WAKE_LOCK
- 有四种 flag 对应不同的 level:
- PARTIAL_ WAKE_LOCK:保持 CPU 运转,屏幕和键盘灯有可能是关闭的。
- SCREEN_ DIM_WAKE_LOCK:保持 CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯
- SCREEN_ BRIGHT_WAKE_LOCK:保持 CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯
- FULL_ WAKE_LOCK:保持 CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度
- ACQUIRE_ CAUSES_WAKEUP:正常唤醒锁实际上并不打开照明。相反,一旦打开他们会一直仍然保持(例如来世 user 的 activity)。当获得 wakelock,这个标志会使屏幕或/和键盘立即打开。一个典型的使用就是可以立即看到那些对用户重要的通知。
- ON_ AFTER_RELEASE:设置了这个标志,当 wakelock 释放时用户 activity 计时器会被重置,导致照明持续一段时间。如果你在 wacklock 条件中循环,这个可以用来减少闪烁
- 因此必须加个权限:
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
@Override
public void onCreate() {
super.onCreate();
if (DEBUG) Log.d(TAG, "CREATING: " + this);
if (Build.VERSION.SDK_INT >= 26) {
mJobImpl = new JobServiceEngineImpl(this);
mCompatWorkEnqueuer = null;
} else {
mJobImpl = null;
ComponentName cn = new ComponentName(this, this.getClass());
mCompatWorkEnqueuer = getWorkEnqueuer(this, cn, false, 0);
}
}
这种区分在 onCreate 里也有体现,这里看看 Android O 之后的实现——JobServiceEngineImpl
/**
* This is a task to dequeue and process work in the background.
*/
final class CommandProcessor extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
GenericWorkItem work;
if (DEBUG) Log.d(TAG, "Starting to dequeue work...");
while ((work = dequeueWork()) != null) {
if (DEBUG) Log.d(TAG, "Processing next work: " + work);
onHandleWork(work.getIntent());
if (DEBUG) Log.d(TAG, "Completing work: " + work);
work.complete();
}
if (DEBUG) Log.d(TAG, "Done processing work!");
return null;
}
@Override
protected void onCancelled(Void aVoid) {
processorFinished();
}
@Override
protected void onPostExecute(Void aVoid) {
processorFinished();
}
}
由此可见,最终还是通过了 AsyncTask 执行任务,而且是在任务线程里回调 onHandleWork
@Override
void enqueueWork(Intent work) {
if (DEBUG) Log.d(TAG, "Enqueueing work: " + work);
mJobScheduler.enqueue(mJobInfo, new JobWorkItem(work));
}
最终,这个任务还是通过 JobScheduler 来调度的
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论