kotlin 如何在Android中创建生命周期感知处理程序?

dz6r00yl  于 2023-05-01  发布在  Kotlin
关注(0)|答案(4)|浏览(148)

首先,我知道如何创建Handler。
我正在做一个项目,我使用HandlerpostDelayed。有些时候,应用程序会崩溃,因为activity被销毁,处理程序中的任务在activity销毁后执行
我正在寻找一个处理程序,可以延迟后执行的替代品,它可能是生命周期意识,使应用程序不会崩溃。
我知道如何取消处理程序(在活动的onDestroy/onStop方法中删除处理程序或取消处理程序),这里是link。但我并不是在寻找这些解决方案。如果可以的话,任何替代方案都是更好的解决方案。
先谢谢你了!

yk9xbfzb

yk9xbfzb1#

根据你使用的是java还是Kotlin,你可以使用RxJava或协程来实现这个目标。

RxJava解决方案

// this should be a member variable
private final CompositeDisposable disposables = new CompositeDisposable();

// this is how you launch the task that needs delay
Disposable d = Single.timer(2, TimeUnit.SECONDS)
    .subscribeOn(Schedulers.io())
    .observeOn(schedulers.ui())
    .subscribe(ignored -> {
        // you can manipulate the ui here
     });
        
// make sure to call disposables.clear() in onDestroyView
disposables.add(d);

Kotlin解决方案

viewLifecycleOwner.lifecycleScope.launchWhenResumed {
   withContext(Dispatchers.IO) {
       delay(2000)
   }
   // you can manipulate the ui here
}

正如你所看到的,Kotlin+协程解决方案需要更少的手动工作,而且更难出错,所以如果你在一个Kotlin项目上,我认为你应该使用它。其他的选择可能是使用GuavaListenableFuture s,但我还没有使用这些。

jtjikinw

jtjikinw2#

如果您使用Handler来执行postDelayed()的延迟操作,则可能会在Activity或Fragment被销毁后执行操作时遇到麻烦。
有一个简单的解决办法。将处理程序绑定到生命周期。

创建LifecycleObserver

首先让我们创建一个LifecycleObserver,它获取一个Handler示例。在Lifecycle.Event.ON_DESTROY的情况下,它将删除来自Handler的所有回调和消息。

class LifecycleObververHandler(private val handler: Handler) : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    internal fun onDestroy() {
        handler.removeCallbacksAndMessages(null)
    }
}

将LifecycleObserver添加到LifecycleOwner中

接下来,我们必须将LifecycleObververHandler添加到LifecycleOwner。我们还希望轻松创建这些生命周期观察处理程序。因此,让我们创建一个LifecycleHandlerFactory
这个工厂是用lambda handlerFactory创建的,它提供了一个Handler的示例(默认是带有主Looper的Handler)。它有一个函数create,它需要一个LifecycleOwner
在该函数中,它检查Lifecycle的状态是否不是DESTROYED。它调用handlerFactory来获取Handler的示例。然后它创建一个LifecycleObserverHandler,它接受处理程序,并将Observer添加到LifecycleOwner。最后返回Handler

class LifecycleHandlerFactory(private val handlerFactory: (() -> Handler) = { Handler(Looper.getMainLooper()) }) {

    fun create(owner: LifecycleOwner): Handler {
        check(owner.lifecycle.currentState != Lifecycle.State.DESTROYED) {
            "Cannot create a Handler for a destroyed life-cycle"
        }
        val handler = handlerFactory.invoke()
        val observer = LifecycleObververHandler(handler)
        owner.lifecycle.addObserver(observer)
        return handler
    }
}

注入生命周期感知的Handler

当您使用DependencyInjection Framework或像Koin这样的服务定位器时,您可以注入生命周期感知的Handler

module {
  // a single instance of LifecycleHandlerFactory
  // it gets a lambda that every time its being called returnes a new Handler with a main looper.
  single { LifecycleHandlerFactory() }
  
  // uses the LifecycleHandlerFactory to create a new handler with a LifecycleOwner as parameter.
  factory<Handler> { (lifecycleOwner: LifecycleOwner) -> get<LifecycleHandlerFactory>().create(lifecycleOwner) }
}

最后,您可以在片段(或Activity)中注入生命周期处理程序。

// injects a new handler with a LifecycleOwner as a parameter
private val handler: Handler by inject { parametersOf(viewLifecycleOwner) }
ztigrdn8

ztigrdn83#

如果您熟悉并同意使用coroutines,则可以替换Handlers以实现相同的功能
使用以下与协程的依赖关系,您可以使协程的生命周期感知

implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"

然后在活动中

lifeCycleScope.launchWhenStarted{
     delay(1000)

     //do your work after delay, runs on main thread 
     //by default, will be cancelled if life cycle is inactive
}

关于使用协程的更多信息:Deep Dive into Coroutines + Android

pcww981p

pcww981p4#

launchWhenResumed()现在被弃用了,现在的解决方案似乎是这样的:

lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.RESUMED) {
            delay(2000)
            yourFunction()
        }
    }

你可以使用下面的小助手:

fun LifecycleOwner.delayed(
    timeMillis: Long,
    state: Lifecycle.State = Lifecycle.State.RESUMED,
    block: () -> Unit
) {
    lifecycleScope.launch {
        repeatOnLifecycle(state) {
            delay(timeMillis)
            block()
        }
    }
}

比如:

delayed(2000) { yourFunction() }

相关问题