Реакция на жизненный цикл активности во ViewModel - PullRequest
0 голосов
/ 29 сентября 2018

Я пытаюсь создать приложение, которое будет использовать архитектуру MVVM, и есть одна вещь, которую я совершенно не понимаю.

Официальные документы для Android говорят, что не очень хорошая идея ссылаться на контекст активности в ViewModel (какViewModel может пережить активность), поэтому я начал задаваться вопросом о сценарии использования, когда я хочу выполнить какое-либо действие, когда моя деятельность возобновляется.

Я знаю, что ViewModel не должен сам выполнять бизнес-логику, но даже если я использую какой-то сервискласс (скажем, GPSService, который должен запускать и приостанавливать действие по времени каждый раз, когда приостановлен), и внутри этого сервиса я реагирую на действие onResume (с помощью обозревателя жизненного цикла).к наблюдаемой активности это может вызвать утечку активности (поправьте меня, если я ошибаюсь).

Итак, мой вопрос, как реагировать на жизненный цикл активности или фрагмента в архитектуре MVVM?

1 Ответ

0 голосов
/ 03 октября 2018

Я знаю, что ViewModel не должен сам заниматься бизнес-логикой

Да, вы правы.ViewModel не должен содержать бизнес-логику, но он должен содержать логику, связанную с пользовательским интерфейсом.Таким образом, в принципе, в логике ViewModel следует избегать вызовов API или некоторых вещей, связанных с местоположением.

Так что, если вы хотите создать сценарий, который может реагировать на любой жизненный цикл активности?Я предлагаю вам использовать LifecycleObserver.

Почему? Поскольку LifecycleObserver предоставит вам обратные вызовы, как только LifecycleOwner изменит свое состояние.

Что такое LifecycleOwner здесь? В нашем случае это может быть Активность / Фрагмент .


Итак, как этого достичь?

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

Итак, для этого вы можете создать класс с именем LocationUpdates как LifecycleObserver, как показано ниже:

class LocationUpdates : LifecycleObserver {

constructor(){
    // some basic location related initialization here
}

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun connectListener() {
    // this method will respond to resume event of our Lifecycle owner (activity/fragment in our case)
   // So let's get location here and provide callback
}

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun disconnectListener() {
    // this method will respond to pause event of our Lifecycle owner (activity/fragment in our case)
   // So let's stop receiveing location updates here and remove callback
}

@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) // Optional if you want to cleanup references
fun cleanUp() {
    // this method will respond to destroy event of our Lifecycle owner (activity/fragment in our case)
   // Clean up code here
}
}

Теперь из вашей деятельности вы можете сделатьLocationUpdates и получение обратного вызова.

class MyActivity : AppCompatActivity() {

private lateinit var mLocationUpdates: LocationUpdates

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    //Initialize your LifecycleObserver here & assign it to this activity's lifecycle
    lifecycle.addObserver(mLocationUpdates)
}
}

Вы можете обратиться к , как обрабатывать жизненный цикл & Пример кодовых меток .


Редактировать:

Если вы хотите иметь ViewModel для этой работы, учтите это:

class MyViewModel : ViewModel {
private lateinit var mLocationUpdates: LocationUpdates

constructor() : super() {
    // initialize LocationUpdates here
}

// Assign our LifecyclerObserver to LifecycleOwner
fun addLocationUpdates(lifecycle: Lifecycle){
    lifecycle.addObserver(mLocationUpdates)
}

//Optional, we really don't need this.
fun removeLocationUpdates(lifecycle: Lifecycle){
    lifecycle.removeObserver(mLocationUpdates)
}
}

Если ваш LocationUpdates зависит от Context, рассмотритеиспользуя AndroidViewModel.

Теперь мы можем наблюдать за обновлениями нашего местоположения при любых действиях.Vity / фрагмент, используя LiveData, и присвойте наш LifecycleObserver, как показано ниже:

class MyActivity : AppCompatActivity() {

private val viewModel: MyViewModel by lazy {
    return@lazy ViewModelProviders.of(this@MyActivity).get(MyViewModel::class.java)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    viewModel.addLocationUpdates(lifecycle)
}
}

Обратите внимание: еще многое нужно покрыть, но сделав этот ответкак можно короче.Так что, если вы все еще не понимаете что-то связанное, пожалуйста, не стесняйтесь спрашивать меня в комментариях.Я отредактирую свой ответ.

...