以这种方式制作启动画面安全吗?

Is it safe to make a splash screen this way?

我已经为我的应用制作了启动画面,但我不确定这是否是最佳选择。因为它在应用程序启动时正在休眠线程。这是代码,我使用导航组件,所以没有可用的教程。 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(时间)冻结了UI。所以使用Handler延迟启动。

更新启动功能:

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

目前看起来很安全,因为您只睡了 500 毫秒的胎面。但是如果以后增加睡眠时间就不安全了。

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

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

你的解决方案很好,但它不安全,当你调用 start 时它无论如何都会产生一个新的 Threadthreadsleep 一切都很好到目前为止,但您需要从 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)
    }
}