Какой контекст получает BroadcastReceivers при прослушивании BOOT_COMPLETED?

Менеджеры будильников в Android теряют все свои зарегистрированные будильники, когда телефон теряет питание.

Я использую следующий широковещательный приемник для запуска при загрузке Android:

public class AlarmBootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
            Cursor alarmCursor = MainActivity.dbHelper.loadAlarms();
            // Iterate through every stored alarm and set those alarms.
            // ....
            alarmCursor.close();
        }
    }
}
  • Когда onReceive широковещательного приемника запускается при загрузке системы, какой параметр контекста передается методу? Я должен знать контекст, потому что мне нужен контекст для отмены сигналов тревоги, установленных в этом контексте.

  • Я предполагаю, что вызов MainActivity.dbHelper.loadAlarms() небезопасен, поскольку MainActivity не инициализируется при загрузке системы. Или это безопасно, потому что dbhelper и loadAlarms() инициализированы и объявлены статическими?


comment
Тип контекста не имеет значения, что более важно, вы не должны заниматься этим самостоятельно. Для этого существует несколько решений в фреймворке или библиотеках Google. Первый вариант: планировщик заданий API. Второй вариант: задачи, запланированные с помощью GcmNetworkMamager. Так далее...   -  person Xaver Kapeller    schedule 25.12.2016


Ответы (2)


Когда onReceive широковещательного приемника запускается при загрузке системы, какой параметр контекста передается методу? Я должен знать контекст, потому что мне нужен контекст для отмены сигналов тревоги, установленных в этом контексте.

В этом случае вы получите глобальное приложение Context в onReceive(). Однако это не имеет значения. Вам не нужно знать.

Чтобы отменить будильник позже, вы создадите PendingIntent и можете использовать любой Context, который вы хотите сделать. Аварийные сигналы не связаны с конкретным Context, они связаны только с конкретным приложением.

Я предполагаю, что вызов MainActivity.dbHelper.loadAlarms() небезопасен, поскольку MainActivity не инициализируется при загрузке системы. Или это безопасно, потому что dbhelper и loadAlarms() инициализированы и объявлены static?

Если dbHelper действительно равно static и инициализировано при создании экземпляра (не в onCreate()), то этот вызов подходит. В общем, вызов статических методов для действий не одобряется, так как легко сделать что-то глупое, предполагая, что Activity настроен правильно. Вам лучше перенести такие статические методы в общий класс утилит, который не является Activity и содержит только static методов. Это выглядело бы менее подозрительно.

person David Wasser    schedule 26.12.2016

Неважно, какой тип Context получает ваш BroadcastReceiver (в любом случае это ApplicationContext), потому что: 1) Вы не должны использовать DBHelper, связанный с Activity. Вместо этого сделайте его синглтоном и используйте во всем приложении. 2) Ваш AlarmManager должен быть установлен с помощью Service. Итак, неплохо позвонить в службу в вашем onReceive() и установить будильники из этой службы.

person Ankur Aggarwal    schedule 25.12.2016
comment
О, это имеет смысл. Так должен ли DBHelper быть статическим классом со статическими методами? Или это отличается от реализации его как синглтона? Я не уверен, потому что создание инициализируемого DBHelper означает, что я должен где-то хранить его как переменную. Таким образом, разные действия будут создавать экземпляр этого синглтона, предполагая, что моя реализация является потокобезопасной? - person SMP; 25.12.2016
comment
Синглтон отличается от статики. Простой поиск в Google приводит к этому: gist.github.com/Akayh/5566992 - person Ankur Aggarwal; 25.12.2016
comment
Не используйте синглтоны. - person Xaver Kapeller; 25.12.2016