Я ищу элегантный способ мониторинга жизненного цикла приложения, поскольку я работаю над SDK, который должен регистрировать некоторых слушателей. Я хочу отменить регистрацию слушателя, когда приложение переходит в фоновый режим или становится невидимым, а моя библиотека НЕ осведомлена о жизненном цикле приложения.
Например, когда приложение переходит в фоновый режим, я хочу, чтобы слушатель unregister остановил sensorEvent. Однако я не хочу просить моего потребителя явно вызывать другой метод из моего SDK для запуска / остановки службы с уровня их хост-приложения.
Я думал об использовании Lifecycle Arch Components, но мне кажется, что мне все еще нужно попросить потребителя вызвать метод addObserver на уровне хоста для наблюдения. Более того, моя библиотека заключена в другой SDK, который также может иметь или не иметь состояний жизненного цикла.
Какой лучший способ для обычного SDK прослушивать событие жизненного цикла, не запрашивая явный вызов на уровне хост-приложения метода регистрации / отмены регистрации?
Используйте Обратные вызовы жизненного цикла действий. Вы можете сделать что-то вроде предоставления базового класса Application, который выполняет регистрацию, тогда клиентскому приложению потребуется только расширить ваш базовый класс Application.
Я не думаю, что есть способ добиться этого, если клиентское приложение просто включит вашу библиотеку. По крайней мере, должен быть какой-то плагин времени компиляции, который перезаписывает байтовый код клиента для вызова вашего кода. Я точно не знаю, как бы вы это сделали.
Вы можете использовать Компонент архитектуры Android Lifecycle модуль, чтобы добавить облегченный осведомленность о жизненном цикле в вашу собственную библиотеку / приложение.
Фактически, это то, от чего зависят классы библиотеки поддержки (например, FragmentActivity и т. д.). В частности, вам просто нужно включить зависимость жизненного цикла в свою библиотеку, и это просто добавит компонент Lifecycle, не перегружая вашу библиотеку Livedata и ViewModel.
Теперь, используя компонент Lifecycle, вы можете сделать что-то вроде этого:
// using commom-java8 module
public class Falcon implements DefaultLifecycleObserver {
public Falcon(@NotNull LifecycleOwner lifecycleOwner){
// your initialization code
lifecycleOwner.getLifecycle().addObserver(this); // register our instance
}
// Now you can selectively override lifecycle callbacks that you are
// interested in and the Lifecycle component will take care of calling
// them at appropriate time
@Override public void onCreate(@NonNull LifecycleOwner owner){
// library logic here
}
}
Затем потребитель вашей библиотеки может сделать что-то вроде
public SpaceXDashboardActivity extends AppCompatActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// usual code....
Falcon falcon = new falcon(this /* LifecycleOwner */);
}
}
И таким образом вы можете сделать свою библиотеку Android осведомленной о жизненном цикле компонентов, обеспечивая при этом значительную абстракцию от фактического компонента, а также предотвращая утечки памяти!
Обратите внимание, что это решение требует, чтобы вы использовали новую языковую поддержку Java 8 для Android, а также потребителям вашей библиотеки использовать (по крайней мере) версию 26.1.0 SupportLibrary.
Если вы не можете выполнить какое-либо из вышеупомянутых ограничений, вы также можете попробовать решение, показанное на этом посте на Medium
Ах ... Если вы посмотрите на пример Activity в вышеупомянутом посте, он покажется "вполне естественным", что означает наличие без лишнего кода, которое ваш конечный пользователь должен написать. Единственное требование, которое я чувствую, - это то, что конечный пользователь должен использовать Java 8 и Support Library v26 +, а также наличие обходной путь и для этого!. Итак, IMO, если библиотека уже выполняет вашу работу, почему бы не использовать ее?
«Более того, у моего вызывающего абонента может не быть доступа к обратному вызову жизненного цикла» - не могли бы вы уточнить? Вы хотите предоставить своим пользователям доступ к обратным вызовам жизненного цикла или использовать их самостоятельно?
привет, извините за путаницу. Я быстро попробовал ваше решение, и оно действительно работает по некоторым требованиям. Однако, как я уже упоминал, мой вызывающий может не иметь доступа к AppCompatActivity. ваш Falcon falcon = new falcon(this /* LifecycleOwner */); зависит от вызывающего абонента, имеющего доступ к жизненному циклу this. Что мы будем делать без доступа к Lifecycleowner? Можно с applicationContext получить?
Android только управляет - жизненный цикл составные части, который включает Activity, Service, BroadcastReceiver и ContentProvider. Согласно вашему комментарию, если у пользователя нет доступа к ним, он / она должен либо предоставить их, либо им вообще не нужна информация о жизненном цикле !! Короче говоря, вся концепция жизненного цикла вращается вокруг этих составные части, и если вы напрямую не взаимодействуете с ними, вам не нужно беспокоиться об их жизненном цикле ...
Например, посмотрите, как работает Retrofit ... это библиотека HTTP (или REST), которая не взаимодействует активно с Компоненты Android и поэтому не предоставляет никаких осведомленность о жизненном цикле для HTTP-вызовов ... Аналогично, если ваш библиотека не должна активно взаимодействовать с Компоненты Android, тогда вам вообще не нужен осведомленность о жизненном цикле !!!
мой вариант использования - остановить слушателей из моей библиотеки, таких как прослушиватель местоположения ... и т. д. В этом случае мне нужно будет попросить их передать ссылку.
Почему бы вам не отправить Android Service с вашей библиотекой и не попросить вашего пользователя перенести bindService() на ваш Service, таким образом, вы можете получать вызовы жизненного цикла из первых рук без каких-либо дополнительных требований со стороны пользователя (и без какой-либо дополнительной библиотеки)? ??
В любом случае вашему пользователю нужен хотя бы какой-то способ создать экземпляр вашей библиотеки, поскольку вы не можете автоматически запустить свою библиотеку. Я предполагаю, что написание однострочного кода - это не большие накладные расходы, и ваше беспокойство здесь не актуально ....
Пожалуйста, проверьте формулировку вопроса еще раз, что я действительно не хочу использовать библиотеку
arch component, так как это все еще требует дополнительных изменений кода на уровне хост-приложения. Более того, у моего вызывающего абонента может не быть доступа к обратному вызову жизненного цикла.