AlarmManager를 정시에 사용하지 않는 솔루션

        최근 저희 회사의 제품은 고객으로부터 예정된 종료가 제 시간에 이루어지지 않고 가끔 작동하지 않는다는 불만을 제기했습니다. 특정 반복 작업은 비교적 오랜 시간이 지나면 자동으로 종료되며 이러한 확률 문제는 발생하기 쉽습니다.

        이 예정된 종료 기능은 이전 동료에 의해 구현되었으므로 코드를 확인하고 추적 코드를 확인해야 하며 타이밍 메서드가 AlarmManager에서 set() 메서드를 사용했음을 발견했습니다.

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, setTime, pendingIntent);

        나는 그것을 직접 디버깅하고 단기 타이밍이 기능을 정상적으로 실현할 수 있음을 발견 한 다음 10 시간 타이머를 조정하여 종료하고 실제로 오류가 있음을 발견했으며 종료가 3 분 동안 지연되었습니다. 

문서 및 기타 정보 참조:

        공식 문서에서는 전원을 절약하기 위해(시스템 깨우기 및 배터리 사용 감소) API19(android4.4)를 시작하도록 제안합니다. Alarm.set() 및 Alarm.setRepeating() 사용은 정확성을 보장하지 않습니다. API19 이상은 setWindow() 및 setExact()라는 두 가지 다른 정확한 Alarm 메서드를 사용해야 합니다.

하지만 Android 8.0에서 setExact() 메서드를 사용한 후에도 여전히 오랫동안 시간을 ​​지키지 않는다는 것을 알았고 계속해서 정보를 확인했으며 API23(Android 6.0) 이후에 공식에서 새로운 애플리케이션 인터페이스를 추가한 것을 발견했습니다. :

 그런 다음 끈기 있게 인터페이스 메서드를 setExactAndAllowWhileIdle()로 변경합니다.

        그런데 이상하게도 안드로이드 8.0에서 이 인터페이스를 사용하고 10시간으로 장시간 타이머를 설정한 다음 화면을 꺼도 여전히 시간을 맞추지 못하는 문제가 있어 지연되는 현상이 발생했습니다. 전체 2 분.

        이때 참을성이 없어 다른 구현 방법으로 과감히 변경하기로 했습니다. 타이밍에 AlarmManager를 사용하는 대신 안정성이 정말 걱정됩니다.

해결책

마지막으로 폴링은 설정된 종료 시간을 현재 시간과 비교하는 데 사용됩니다.

        여기에서 ACTION_TIME_TICK 시스템 브로드캐스트를 수신하도록 등록  하고 시스템은 매분 ACTION_TIME_TICK 브로드캐스트를 전송합니다.

 

        방송을 수신할 때마다 비교를 하여 설정된 종료 타임스탬프를 현재 시간과 비교하여 비교 시간의 절대값이 60 미만이면 해당 동작을 수행한다.

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            final String action = intent.getAction();
           
            if (action.equals(ACTION_TIME_TICK)) {

             //setMillionSeconds为设定的定时时间戳
            if (Math.abs(setMillionSeconds - System.currentTimeMillis()) <= 60000) {

                //to do what you whant to do 

            }             
          }
        }
    };


        이 방법을 사용하면 AlarmManager를 사용하는 것보다 훨씬 안정적입니다! AlarmManager에서 설정한 시간을 다시 불러올 수 있는지 여부는 형이상학입니다!

그러나 ACTION_TIME_TICK 브로드캐스트에는 동적 등록이 필요하다는 점에 유의해야 합니다.

추천

출처blog.csdn.net/weixin_42433094/article/details/123103829