首先,我知道如何创建Handler。
我正在做一个项目,我正在使用
Handler
和 postDelayed
。有时应用程序崩溃是因为 activity 被销毁并且处理程序中的任务在 activity destroy 之后执行。
我正在寻找 Handler 的替代方案,它可以在延迟后执行,并且它可以是生命周期感知的,这样应用程序就不会崩溃。
我知道如何取消 Handler(删除 Handler 或取消活动的 onDestroy/onStop 方法中的处理程序),这是相同的link。但我不是在寻找这些解决方案。如果可以的话,任何替代方案都会是更好的解决方案。
提前致谢!
根据您使用的是 java 还是 Kotlin,您可以为此使用 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);
viewLifecycleOwner.lifecycleScope.launchWhenResumed {
withContext(Dispatchers.IO) {
delay(2000)
}
// you can manipulate the ui here
}
如您所见,Kotlin + 协程解决方案需要的手动工作少得多,而且更难出错,所以如果您在 Kotlin 项目上,我认为您应该使用那个。其他选择可能是使用 Guava
ListenableFuture
s 但我还没有使用过这些。
如果您使用
Handler
来执行带有 postDelayed()
的延迟操作,当您的 Activity 或 Fragment 被销毁后执行操作时,您可能会遇到麻烦。
对此有一个简单的解决方案。将您的处理程序绑定到生命周期。
首先让我们创建一个
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)
}
}
接下来我们必须将
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
}
}
当您使用 DependendencyInjection 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) }
}
最后,您可以在片段(或活动)中注入生命周期处理程序。
// injects a new handler with a LifecycleOwner as a parameter
private val handler: Handler by inject { parametersOf(viewLifecycleOwner) }
如果您熟悉并且可以使用
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
}
关于使用协程的更多信息:深入研究协程 + Android
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() }