Лучшая практика для запуска бесконечной фоновой службы на android устройствах с настраиваемой ОС - PullRequest
2 голосов
/ 04 августа 2020

Как лучше всего запустить службу, которая никогда не останавливается? Я должен иметь возможность отправлять уведомления в c раз. Как указано Здесь диспетчер работы, диспетчер сигналов тревоги, служба заданий (или любая другая служба) не будут работать должным образом на устройствах с настраиваемой ОС, таких как Xiaomi. Некоторые методы, такие как this , могут быть полезны для anroid O + (с учетом ограничений фоновых служб), но не работают на устройствах с настраиваемой ОС с оптимизацией батареи, таких как Xiaomi. Я даже поднял этот трекер проблем , и они подтвердили, что эта проблема реальна с пользовательскими устройствами с ОС! (Они сказали, что разговаривают с ними, чтобы что-то с этим сделать!)

Так или иначе, я нашел приложение, которое могло отправлять уведомления в очень точное время. Он отлично работает на всех устройствах. Из любопытства я декомпилировал их приложение. Большая часть кода была нечитабельной, но я нашел класс с именем WakeFulBroadcasReceiver, который, похоже, запускает множество служб и создает экземпляры многих wakelocks. Но я не мог понять, как они на самом деле это делают. Вот часть кода, которая осталась нетронутой:

public abstract class WakefulBroadcastReceiver extends BroadcastReceiver {
public static final String EXTRA_WAKE_LOCK_ID = "androidx.contentpager.content.wakelockid";
public static int mNextId = 1;
public static final SparseArray<PowerManager.WakeLock> sActiveWakeLocks = new SparseArray<>();

public static boolean completeWakefulIntent(Intent intent) {
    int intExtra = intent.getIntExtra(EXTRA_WAKE_LOCK_ID, 0);
    if (intExtra == 0) {
        return false;
    }
    synchronized (sActiveWakeLocks) {
        PowerManager.WakeLock wakeLock = sActiveWakeLocks.get(intExtra);
        if (wakeLock != null) {
            wakeLock.release();
            sActiveWakeLocks.remove(intExtra);
            return true;
        }
        Log.w("WakefulBroadcastReceiv.", "No active wake lock id #" + intExtra);
        return true;
    }
}

public static ComponentName startWakefulService(Context context, Intent intent) {
    synchronized (sActiveWakeLocks) {
        int i2 = mNextId;
        int i3 = mNextId + 1;
        mNextId = i3;
        if (i3 <= 0) {
            mNextId = 1;
        }
        intent.putExtra(EXTRA_WAKE_LOCK_ID, i2);
        ComponentName startService = context.startService(intent);
        if (startService == null) {
            return null;
        }
        PowerManager.WakeLock newWakeLock = ((PowerManager) context.getSystemService("power")).newWakeLock(1, "androidx.core:wake:" + startService.flattenToShortString());
        newWakeLock.setReferenceCounted(false);
        newWakeLock.acquire(OpenStreetMapTileProviderConstants.ONE_MINUTE);
        sActiveWakeLocks.put(i2, newWakeLock);
        return startService;
    }
}

}

Похоже, у них есть массив Wakelocks, что очень странно. Есть ли у вас какие-либо идеи относительно того, что нужно сделать, чтобы фоновая служба всегда работала на этих устройствах cusomt OS?

...