Android 8을 통해 JobScheduller의 정기적인 실행 확인

개요


이 내용은 안드로이드의 JobScheduller 클래스가 안드로이드 8에서 정기적으로 실행되고 그 행동을 확인한 결과를 요약한다.
이번에는 프로그램이 미터기와 같은 기능을 실현해야 하기 때문에 그 용도에 적합한지 검증하는 것을 목적으로 진행했다.

JobScheduler


JobScheduler는 안드로이드 5.0(API21)에 추가된 지정된 일정에 따라 백그라운드에서 처리를 수행하는 메커니즘을 말한다.특정 시간 후에 실행할 수 있으며, 이러한 동작을 지정한 간격으로 실행할 수 있습니다. (여기서는 언급하지 않지만, 터미널의 상태와 새로운 그림·애니메이션이 추가된 시간을 터치로 실행할 수도 있습니다.)이전 버전에서는 AlarmManager 등을 사용했다.
구글 I/O 2018에 발표된'JetPack'에서는 안드로이드 버전 전환 처리WorkManager에 따라 앞으로 그것을 사용해야 한다고 생각했다.이걸 이용하면 내부는 아래처럼 전환 처리됩니다.
  • API23 이후 JobScheduller
  • 사용
  • API 14-22
  • Firebase JobDispatcher가 이용할 수 있는 상황에서 그곳
  • 을 이용한다
  • 그렇지 않으면 Alarm Manager 및 BroadcastReceiver
  • 를 사용합니다.
    이 컨텐트는 항상 JobScheduller의 동작에 대한 확인이므로 WorkManager를 사용하지 않습니다.신지현: 시도할때 몰랐다고 할 수도 있지만...

    안드로이드 8 이후 배경 처리


    안드로이드 8에서는 배경 동작이 제한됩니다.이것은 응용 프로그램이 사용자가 의도하지 않은 자원을 소모하는 것을 방지하기 위해서이다.
    백그라운드 실행 제한
    https://developer.android.com/about/versions/oreo/background?hl=ja
    이 때문에 백그라운드 처리를 하는 서비스 수준의 응용이 큰 영향을 받았다.이러한 영향은 개발 시 대상 API가 26개 이상의 애플리케이션을 개발한 데 따른 것입니다.(Google은 개발자에게 목표 API의 하한선을 설정하고 향후 개발될 모든 애플리케이션에 영향을 줄 것을 알려줍니다.)
    따라서 백그라운드에서 서비스를 사용하는 앱을 사용하는 개발자들은 주로 다음과 같은 대책에 직면해 있다.
  • startForeground 서비스에서 서비스를 실행하고 알림 표시줄에 아이콘을 표시하고 실행
  • 서비스를 JobSchedule
  • 로 교체
    이외에도 푸시 알림과 특정 활용 등 일부 예외가 있지만 기본적으로 개발자가 마음대로 백그라운드 동작을 할 수 없다.

    JobScheduller의 정기적인 동작


    이번에는 정기적으로 특정 처리를 하기 위해 잡스cheduller를 사용할 수 없는지를 논의하기로 했다.JobScheduller의 주요 동작 사양은 다음과 같습니다.
  • 정기적으로 실행되는 경우 각 작업 ID에 대해 최소 15분의 실행 간격을 지정할 수 있습니다.그보다 작은 간격을 지정해도 15분으로 설정된다.
  • 실행 간격 전후로 정확한 주기를 보장하지 않습니다.
  • 최대 실행 시간은 약 10분입니다.(5.1.1까지 1분 정도 걸리는 듯)

  • DOZE 상태에서 동작하지 않고 일정 시간 방문한 유지보수 창에서 집중적으로 실행됩니다.
  • 동시에 실행할 수 있는 작업의 수량은 상한선이 있고 환경에 따라 다르다.
  • 실제로 행동해 보세요.


    나는 실제 상황을 확인하기 위해 간단한 테스트 프로그램을 만들었다.일정한 주기로 걸음수를 얻어 그것을 출력하고 있다.
    이때 JobScheduller에 설정된 JobInfo는 다음과 같습니다.실행 간격은 0이지만 값은 15분보다 작기 때문에 내부는 15분으로 설정해야 합니다.setPersisted와 setRequiredNetworkType은 이번에 아무런 관계가 없기 때문에 통과했습니다.
    JobInfo info = new JobInfo
            .Builder(0) // JobID=0の指定
            .setPersisted(true) // 端末再起動後も実行する
            .setPeriodic(0, JobInfo.getMinFlexMillis()) // 実行間隔=0と実行遅延許容時間の指定
            .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE) // ネットワーク状態と無関係に実行
            .build();
    scheduler.schedule(info);
    
    출력 결과는 다음과 같습니다.18:58:01부터 00:15:10까지 측정됩니다.

    대충 보면 15분 간격으로 집행되는데 정확하지 않아요.일정 시간이 지나면 5분 정도의 편차가 발생해 편차가 발생하며 터미널이 얕은 도즈 상태로 진입한 것으로 추정된다.
    다음은 시간을 보고 조금 더 앞으로 밀고 나갈 때의 데이터를 살펴보자.

    여기서는 3시가 지나 오전 8시께 휴대전화 조작이 완전히 멈췄다.4시~7시쯤이면 실행 간격이 급격히 길어지는 것을 알 수 있다.이는 터미널이 깊이 도즈 상태에 들어간 것으로 여겨진다.
    애초에 자신의 집행 간격이 길어져도유지보수 창의 시간에 한 번에 주기적으로 처리(즉 1시간 정지 후 4회)하지만 단순히 실행 간격을 연장한 것 같다.

    여러 JobSchedule에서 정기적으로 실행


    나는 이곳에서 몇 가지 실험을 했다.실행 간격은 JobInfo에 설정된 각 JobID에 대해 지정되며, 여러 개의 다른 처리를 타이밍을 어긋나면 더 짧은 간격의 정기적인 실행 처리를 위선적으로 재현할 수 있습니다.
    한 마디로 하면 우리는 1분 주기로 실행하는 처리를 실현하는 것을 고려했다.
    이렇게 하려면 여기에 두 종류의 JobSchedule을 만듭니다.첫 번째 JobScheduller는 지정된 시간 후에 처리를 실행하고, 두 번째 JobScheduller는 정기적으로 처리를 실행합니다.첫 번째 JobScheduller, 두 번째 JobScheduller를 칩니다.15분 동안 1분 간격으로 운행하기 위해 두 번째 JobScheduller는 15개의 실례가 필요하다.
    첫 번째 JobScheduller의 JobInfo입니다.
    // 15個のJobSchedulerを実行
    for (int i = 1001; i <= 1015; i++) {
        JobInfo info1 = new JobInfo
                .Builder(i, componentName) // JobIDが被らないように、1001〜1015を設定
                .setPersisted(true)
                .setMinimumLatency((i - 1001) * (1000 * 60)) // 1〜15分後に実行
               .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE)
               .build();
        scheduler.schedule(info);
    }
    
    두 번째 JobScheduller의 JobInfo입니다.
    JobInfo info2 = new JobInfo
            .Builder(jobParameters.getJobId() - 1000, componentName) // JobIDに1〜15を設定
            .setPersisted(true)
            .setPeriodic(0, JobInfo.getMinFlexMillis())
            .setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE)
            .build();
    scheduler.schedule(info);
    
    결과는 다음과 같다.이번에 GPS 정보를 함께 출력했는데 개인 프라이버시 때문에 검은색으로 칠했다.

    대략 1분 주기로 돌아가지만 아직 정확하지 않다.
    잠시 후 아래의 동작으로 변했다.

    02:34:35~근처의 실행 순서(ID의 순서)가 엉망이 되었다.실행 시간을 보면 짧은 시간에 한 번 실행되기 때문에 도즈 상태에서는 유지보수 창 시간에 한 번 실행된 것으로 추정된다.이후 1분 간격의 실행 주기로 돌아간 것 같은데...
    결론적으로 JobScheduller의 실행 주기는 편차가 있어서 믿을 수 있는 것이 아니라 Doze 상태에서 동작이 바뀌어 결과를 읽을 수 없기 때문에 이런 번거로운 실시를 멈추는 것이 좋다고 생각합니다.

    총결산


    이번 확인을 통해 잡스cheduller의 특성을 어느 정도 파악했다.JobScheduller는 백그라운드에서 정기적으로 처리하려고 할 때 사용할 수 있지만 실행 간격과 실행 시기를 믿을 수 없습니다.
    이에 따라 목적을 위해 잡스cheduller를 채용하는 것은 부적절하다고 판단해 채용을 미뤘다.그러나 이런 실험을 통해 장점과 단점을 엿볼 수 있어 향후 채용 판단에 도움이 될 것으로 보인다.

    주요 참고 자료

  • Jobscheduller의 기본
    https://qiita.com/naoi/items/f1d00a79196d3d2d3a81
  • 안드로이드 M/N의 Doze 제한 및 배경 작업 수행에 대한 요약
    https://qiita.com/FumihikoSHIROYAMA/items/b1d6dbda120462d0e209
  • 좋은 웹페이지 즐겨찾기