用这种方式制作开机画面安全吗?



我已经为我的应用程序做了这个启动屏幕,但我不确定这是否是最好的选择。当应用程序启动时,线程处于睡眠状态。下面是代码,我使用导航组件,所以没有可用的教程。SplashFragment.kt

class SplashFragment : Fragment() {
private lateinit var rootview:View
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
splash()
rootview = inflater.inflate(R.layout.fragment_splash, container, false)
return rootview
}
fun splash(){
Thread(Runnable {
Thread.sleep(500)
findNavController().navigate(R.id.action_splahFragment_to_loginFragment)
}).start()
}

}

Thread.sleep(time)冻结UI。所以使用Handler来延迟启动。

更新splash功能:

fun splash(){
Handler(Looper.getMainLooper()).postDelayed(Runnable {
findNavController().navigate(R.id.action_splahFragment_to_loginFragment)
}, 500)
}

你的解决方案是好的,但它是不安全的,它无论如何都会产生一个新的Thread,当你调用startthreadsleep所有好的到目前为止,但你需要从UI线程调用navController,也如果用户退出应用程序之前500毫秒,它会崩溃。

这是Kotlin coroutines方法的解决方案

val mDelayJob: CompletableJob = Job() 
//use mDelayJob to cancel coroutine in onStop, so if even user exits before delay, nothing will happen
fun splash(){
CoroutineScope(Dispatchers.Main).launch(mDelayJob){
delay(500)
findNavController().navigate(R.id.action_splahFragment_to_loginFragment)
}
}

现在看起来很安全,因为你只睡了500毫升的胎面。但如果你将来增加睡眠时间,那就不安全了。

让我解释一下如何,假设你正在睡眠一个线程10000磨(即10秒),在10秒之前,如果你导航到任何其他组件(说片段或活动),然后当10秒后,当你的线程试图执行下一行,这个片段将不可见,并会导致问题。

因此,作为最佳实践,您将中断您的片段的onStop方法上的线程,并仔细检查内部可运行,即您的线程是否中断。如果没有中断,则只执行下一个任务

最新更新