Android 잡 스케줄러

timothy jeong·2021년 11월 15일
0

Android with Kotlin

목록 보기
45/69

앱이 백그라운드 상황일때 서비스를 이용하는 것은 제약을 받지만, 잡 스케줄러를 이용하면 이를 보완할 수 있다. 안드로이드 버전 8부터 서비스 백그라운드 제약이 생기면서 잡 스커줄러의 역할이 더욱 중요해졌다.

잡 스케줄러를 이용한다고 해서 모든 상황의 백그라운드 처리를 할 수 있는 것은 아니다. 잡 스케줄러도 개발자가 만드는 서비스이므로 이 서비스를 어떤 상황에서 실행해야 하는지 조건을 명시해 줘야한다. 이렇게 조건을 명시할 수 있는 상황에서만 백그라운드에서 처리할 수 있다.

잡 스케줄러의 실행 조건

잡 스케줄러에 조건을 명시할 수 있는 상황은 다음과 같다.

  • 네트워크 타입
  • 베터리 충전 상태
  • 특정 앱의 콘텐츠 프로바이더 갱신

네트워크 타입이 변경되거나 배터리 충전 상태가 변경되었을 때, 또는 특정 앱의 콘텐츠 프로바이더가 변경되었을 때를 조건으로 명시할 수 있으며 해당 조건에 부합하면 시스템이 잡 스케줄러를 실행한다. 또한 아래의 조건을 명시할 수 있다.

  • 실행 주기
  • 최소 지연 시간
  • 시스템 재구동 시 현재 조건 유지 여부

잡 스케줄러 구성요소

  • 잡 서비스 : 백그라운드에서 처리할 작업을 구현한 서비스
  • 잡 인포 : 잡 서비스 정보와 실행될 조건을 지정한다.
  • 잡 스케줄러 : 잡 인포를 시스템에 등록한다.

잡 서비스 : 백그라운드 작업 구현

개발자가 만드는 서비스이므로 메니페스트에 등록해야 한다.

<service android:name=".MyJobService"
            android:enabled="true"
            android:exported="true"
            android:permission="android.permission.BIND_JOB_SERVICE"/>

Service 가 아니라 JobService 객체를 상속해야한다.

class MyJobService : JobService(){

    override fun onCreate() {
        super.onCreate()
        Log.d("JOB", "Create")
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("JOB", "Destroy")
    }

    override fun onStartJob(params: JobParameters?): Boolean {
        Log.d("JOB", "Start")
        return false
    }

    override fun onStopJob(params: JobParameters?): Boolean {
        Log.d("JOB", "Stop")
        return false
    }
}

onStartJob() 에 처리할 작업을 구현한다. 이 함수의 반환값은 Boolean 인데 true 는 작업이 끝나지 않았음을, false 는 작업이 끝났음을 의미한다. 여기서 false 를 반환하면 시스템이 더 처리할 필요가 없다고 판단하여 바로 onStopJob() 을 건너뛰고 onDestroy() 함수를 호출해서 서비스를 종료한다.

onStartJob() 함수가 true 를 반환하면 백그라운드에서 처리할 작업이 아직 끝나지 않았다는 것을 의미하며 onDestroy() 함수는 호출되지 않는다, 오랜 시간 살아있는 서비스가 된다. 따라서 올래 걸리는 작업을 스레드 등에서 처리하고 끝날 때 jobFinish() 함수를 호출하는 식으로 onStartJob() 함수를 구현한다.

onStopJob() 함수가 호출되는 경우는 onStartJob() 함수에서 true 를 반환해 서비스가 오랜 시간 살아있는 상황에서 갑자기 잡 스케줄러를 실행하는 조건이 변경되거나 어디선가 cancel() 함수로 취소했을 때이다. 시스템은 이러한 상황을 잡 스케줄러가 비정상으로 종료된 것으로 인지하고 서비스를 종료하기 전에 처리할 로직을 실행하고자 onStopJob() 함수를 호출한다.

onStopJob() 이 false 를 반환하면 잡 스케줄러 등록을 취소하는 것이고, true 를 반환하면 잡 스케줄러를 재등록한다.

잡 인포 : 잡 서비스 실행 조건 정의

var jobScheduler: JobScheduler? = getSystemService<JobScheduler>()

JobInfo.Builder(1, ComponentName(this, MyJobService::class.java)).run {
    setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
    jobScheduler?.schedule(build())
}

JobInfo.Builder 생성자의 첫 번째 매개변수는 등록할 작업의 식별자값이다. 나중에 cancel() 함수로 작업을 취소할 때 이 값을 이용한다. 두번째 매개변수는 등록할 잡 서비스이다. 이 서비스르 시스템에 등록하겠다는 의미이다. 그리고 빌더의 세터 함수를 이용해 조건을 명시한다. 이렇게 만든 JobInfo 객체를 JobScheduler 의 schedule() 함수로 시스템에 등록하면 된다.

JobInfo.Builder 에 지정한 잡 서비스가 실행되는 조건을 명시할 때는 다음과 같은 세터 함수를 이용한다.

  • setPersisted(true) : 기기를 재부팅해도 작업 등록을 유지하는지 설정
  • setPeriodic(long intervalMillis) : 작업의 실행 주기를 설정
  • setMinimumLatency(long maxExecutionDelayMillis) : 작업의 실행 지연 시간을 설정
  • setOvrrideDeadline(long ...) : 다른 조건에 만족하지 않더라도 작업이 이 시간안에 실행되어야 함
  • setRequiredNetworkType(int networnType): 네트워크 타입 설정
  • setRequiredBatteryNoLow(boolean) : 베터리가 낮은 상태가 아닐때만 작업 등록 유지 여부
  • setRequiresCharging(boolean) : 베터리 충전상태일 때만 작업 등록 유지 여부

이 중에서 setPersisted() 함수를 true 로 전달하려면 메니페스트에 anroid.permission.RECEIVE_BOOT_COMPLETED 를 퍼미션을 선언해야한다. setPeriodic() 함수로 실행주기를 설정할 때는 최소 15분 이상이어야 한다. 이 함수로 실행 주기를 설정하더라도 정확한 시간을 보장하지 않는다. 주어진 시간 내에 한번은 반복된다.

잡 스케줄러 : 잡 서비스 등록시 데이터 전달

잡 서비스에 데이터를 전달하려면 JobInfo.Builder 의 setExtras() 함수를 이용한다.

val jobScheduler: JobScheduler? = geySystemService<JobScheduler>()
val extras = PersistableBundle()
extras.putString("extra data", "hello")

val builder = JobInfo.Builder(1, componentName)
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
builder.setRequiresCharging(true)
builder.setExtra(extras)
val jobInfo = builder.build()

jobScheduler!!.scheduler(jobInfo)

이렇게 전달된 데이터를 가져올때는 잡 서비스에서 onStartJob() 에 jabparameter.extras.getString 처럼 하면 된다.

profile
개발자

0개의 댓글