# 안드로이드 잡인텐트서비스 : Android Jobintentservice
## 원본
- [Android O에서의 백그라운드 처리를 위한 JobIntentService](https://medium.com/til-kotlin-ko/android-o에서의-백그라운드-처리를-위한-jobintentservice-250af2f7783c)
#### 참고
[JobIntentService](https://developer.android.com/reference/android/support/v4/app/JobIntentService)
[[android] JobIntentService 소개 (tutorial)](https://aroundck.tistory.com/5799)
[WorkerResultReceiver - Best Practise JobIntentService Android Example](http://thoughtnerds.com/2018/02/best-practise-jobintentservice-android-example/)
[JobIntentService Android Example](https://medium.com/@sambhaji2134/jobintentservice-android-example-7f58bd2720bf)
https://github.com/JimSeker/service
[Doze 및 앱 대기 모드 최적화](https://developer.android.com/training/monitoring-device-state/doze-standby)
[Continually Running Background Service](https://stackoverflow.com/questions/51289236/continually-running-background-service/51360718#51360718)
#### Comparison to other libraries
Library
Minimum API
Requires Google Play
Service API1
Custom retry strategies
Framework JobScheduler
21
No
JobScheduler
Yes
Firebase JobDispatcher
14
Yes
JobScheduler
Yes
evernote/android-job
14
No2
Custom
Yes
Android WorkManager3
14
No2
Custom
Yes
---
### JobIntentService?
- Supoort Library v4
- Oreo+ : JobScheduler.enqueue,
JobInfo.setOverrideDeadline(0)로 고정
- Oreo- : Context.startService ( Background service )
- Wakelock을 알아서 관리함, 하위 버전에서 WakefulBroadcastReceiver 사용할 필요 없음
실수로 인한 배터리 소모 등의 이슈를 원천적으로 해결해줌.
- **[JobIntentService는 단지 서비스 일 뿐이며, 주기적으로 실행되는 것을 의미하지는 않습니다.](https://stackoverflow.com/questions/51668607/jobintentservice-runs-periodically)**
- 주기적 실행을 위해 JobScheduler , WorkManager 또는 AlarmManager를 사용해야 합니다.
### JobIntentService의 프로젝트 적용
```javascript
allprojects {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
}
dependencies {
...
compile 'com.android.support:support-compat:26.0.0-beta2'
}
```
### JobIntentService의 특징
1. 시작은 startService가 아니라 enqueueWork로 한다.
1. job의 handle는 IntentService와 다르게 onHandleIntent 대신 onHandleWork()를 통해 설정한다.
1. 시스템에의해 언제든지 onStopCurrentWork()가 호출될 수 있다.
### JobIntentService의 구조
- ##### enqueueWork (Context context, Class cls, int jobId, Intent work)
**: 실행할 동작을 작업 큐에 추가**
* Oreo+ : deadline이 0인 상태로 최대한 빠르게 동작 요청되지만,doze모드, 메모리 부족으로 실행은 임의의 시간에 시작될 수 있음.
* Oreo- : startService()를 호출한 것과 동일하게 백그라운드 서비스가 시작되고 즉시 기능을 수행, doze 모드등과 무관하게 동작하므로, 실행시 Doze에대한 네트워크 타임아웃 등은 별도의 이슈로 관리되어야함.
* 동일한 클래스는 jobID는 모두 같아야 함, 다른 jobId를 부여할경우 N이하 버전 문제 없음, O이상 IllegalArgumentException 발생.
* work는 null 불가, null일 경우 IllegalArgumentException가 발생.
* **JobIntentService의 디컴파일 코드**
```java
@RequiresApi(26)
static final class JobWorkEnqueuer extends JobIntentService.WorkEnqueuer {
private final JobInfo mJobInfo;
private final JobScheduler mJobScheduler;
JobWorkEnqueuer(Context context, Class cls, int jobId) {
...
JobInfo.Builder b = new JobInfo.Builder(jobId, mComponentName);
mJobInfo = b.setOverrideDeadline(0).build(); // point
mJobScheduler = (JobScheduler) context.getApplicationContext().getSystemService(
Context.JOB_SCHEDULER_SERVICE);
}
...
}
```
- ##### onHandleWork(Intent intent)
: 작업 큐에서 dequeue한 처리 작업을 전달받는 메소드
* enqueueWork()에 의해 적재된 인텐트가 실행시 이 메소드로 전달됨
* IntentService와 마찬가지로 적재된 인텐트는 순차적으로 전달됨.
* Wakelock은 첫번째 인텐트부터 최종 인텐트의 완료까지 자동으로 유지됨.
* onHandleWork()이 종료되면, 작업 큐에 적재된 다음 작업이 전달됨.
- ##### onStopCurrentWork()
: 현재 작업이 중지되어야 할 경우 호출됩니다.
* JobService.onStopJob()과 마찬가지로 시스템에서 Job종료 시 호출됨.
- return true : 재스케줄링
- return false : 스케줄링 안함(종료)
- ##### JobIntentService 호출 ( WorkerResultReceiver 를 사용 할 수 있으나 단순하게 호출 )
```java
UpdateJobIntentService.enqueueWork(context, new Intent());
```
- ##### AndroidManifest.xml 파일에 내용 추가
```xml
...
```
### Source
```java
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.JobIntentService;
import android.util.Log;
import android.widget.Toast;
import
/**
* Example implementation of a JobIntentService.
*/
public class UpdateJobIntentService extends JobIntentService {
static final int JOB_ID = 1000;
static final String WORK_DOWNLOAD_ARTWORK = ".DOWNLOAD_ARTWORK";
ArtworkDownloader mDownloader;
static void enqueueWork(Context context, Intent work) {
enqueueWork(context, Update.class, JOB_ID, work);
}
@Override
public void onCreate() {
super.onCreate();
mDownloader = ArtworkDownloader.getSequencialDownloader();
}
@Override
protected void onHandleWork(Intent intent) {
// enqueueWork()에 의해 적재된 인텐트는 여기로 전달됩니다.
if (WORK_DOWNLOAD_ARTWORK.equals(intent.getAction())) {
mDownloader.download(intent.getStringExtra("URL"))
}
}
@Override
public boolean onStopCurrentWork() {
// 현재 처리 중인 동작들을 중지해야 할 경우
return !mDownloader.isFinished();
}
}
```
![](https://cdn-images-1.medium.com/max/1800/1*dh3IGuorki3rHOMUKWtU_g.png)
댓글