본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] JobIntentService 소개 (tutorial)

by 돼지왕 왕돼지 2018. 11. 28.
반응형

[android] JobIntentService 소개 (tutorial)


https://medium.com/til-kotlin/jobintentservice-for-background-processing-on-android-o-39535460e060

https://developer.android.com/reference/android/support/v4/app/JobIntentService

android.permission.BIND_JOB_SERVICE, android.permission.WAKE_LOCK, background service, BIND_JOB_SERVICE, Doze Mode, enqueueWork, IllegalArgumentException, intentservice, jobinfo, JobIntentService, jobscheduler, onhandleintent, onHandleWork, onStopCurrentWork, onStopCurrentWork invoke time, onStopCurrentWork, onStopJob, out of memory, SecurityException, setOverrideDeadline, StartService, SupportLib, WakefulBroadcasdtReceiver, WAKE_LOCK, [android] JobIntentService 소개 (tutorial)



-

JobIntentService 는 SupportLib 에 들어있다.



-

JobIntentService 는 Android O 부터는 JobScheduler 를 사용하고, Android O 이전 단말에서는 background service 를 사용한다.



-

Android O 이전 단말에서는 background 서비스가 즉각적으로 실행된다.

그리고 각각의 job 이 순차적으로 수행된다.

기존의 IntentService 와 동일하다고 보면 된다.



-

Android O 이상에서는 job 이 JobScheduler 를 통해 순차적으로 수행된다.

내부적으로는 jobInfo.setOverrideDeadline(0).build() 를 사용하는데,

dealine 이 0 이라는 의미는 사실 즉각 수행하라는 의미와 동일하다.

( 그러나 요청자체는 저렇지만 무조건 바로 수행됨이 보장되지는 않는다. )



-

그리고 JobScheduler 를 사용하기 때문에 android.permission.BIND_JOB_SERVICE permission 을 주어야 한다. 안 주면 SecurityException 이 발생한다.

<service 

    android:name=“com.example.MyJobIntentService”

    android:permission=“android.permission.BIND_JOB_SERVICE" />



-

WakefulBroadcastReceiver 를 쓸 필요가 없다.

JobIntentService 는 Wakelock 을 알아서 관리해준다.

O 미만에서는 wakelock 을 관리하기 떄문에 permission 은 여전히 필요하다.

<uses-permission android:name=”android.permission.WAKE_LOCK” />`



-

적용하기 위해서는 우선 gradle 에 google maven repo 를 연결해야 한다.

allprojects { 

    repositories { 

        jcenter () 

        maven { 

            url "https://maven.google.com"

         } 

    } 

}



-

dependency 로 support-compat:26 이상이 필요하다.

dependencies { 

   ... 

   compile 'com.android.support:support-compat:26.0.0'

}



-

JobIntentService 의 시작은 startService 가 아니라 enqueueWork 를 통해 시작한다.

그리고 job 의 handle 은 onHandleIntent 대신 onHandleWork 를 통해 한다.


한 가지 큰 차이점이 있다면, JobIntentService 는 system 에 의해 언제든지 onStopCurrentWork() 가 불릴 수 있다는 것이다.






-

enqueueWork(Context context, Class cla, int jobId, Intent work)


Android O 이상에서는 deadline 이 0 으로 설정된다.

그러나 완전 즉각 수행되는것이 perfect 하게 보장되지는 않는다.

doze 모드나 out of memory 등의 상황에서는 이슈가 될 수 있기 때문이다.


Android O 미만에서는 background service 가 startService 를 통해 수행된다.

doze 모드와 관계 없이 작동하기 때문에 doze 모드의 network timeout 등은 알아서 관리되어야 한다.


동일한 class 를 target 하는 경우 jobId 는 항상 같아야 한다.

만약 새로운 jobId 를 주려면 새로운 class 를 정의해야 한다.

이 규칙을 따르지 않는다면, O 미만에서는 문제가 없지만, O 이상에서는 IllegalArgumentException 을 마딱뜨리게 될 것이다.


work Intent 는 null 일 수 없다. (work intent 는 handle 될 녀석이다, onHandleWork 에 전달될 녀석이다.)

null 이면 IllegalArgumentException 이 발생한다.



-

onHandleWork(Intent intent)


여기에 전달되는 intent 는 enqueueWork 를 통해 주입된 intent 이며, queue 에 들어가있다가 순차적으로 처리된다.


Wakelock 은 자동으로 관리가 된다.

그러므로 그냥 job 처리에만 신경쓰면 된다.


onHandleWork 가 마무리되면 queue 에 다음 내용이 있으면 다시 onHandleWork 가 불린다.


이 함수는 bg thread 에서 불린다.



-

onStopCurrentWork()


이 녀석은 job 이 멈춰야 할 때 불린다.

JobService.onStopJob() 과 마찬가지로, 이 녀석은 system 이 job 을 shutdown 시킬 때 부른다.

이녀석이 불리면 work 를 중단하면서 현재 상태를 저장한 후, 다음 기회에 job 을 이어나가야 한다.


reschedule 이 필요하면 true 를 return 한다.

scheduling 이 다시 필요하지 않는다면 false 를 return 한다.



-

http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/job/JobServiceContext.java#EXECUTING_TIMESLICE_MILLIS


위 링크를 보면 얼마나 시간이 지나야 onStopCurrentWork 가 불리는지 감을 잡을 수 있다. (10분)



-

최대한 미뤄라!!


JobScheduler 를 쓰던 뭐던 결국 bg 에서 뭔가 하는 것은 나쁜 UX 일 수 있다.

원하지 않는 타이밍에 battery, memory 등을 사용하기 때문이다.

그래서 최대한 미룰 수 있는 만큼 미룬 후에 수행하라.




반응형

댓글