如何在 Kotlin 中保存延迟帖子的状态

Posted

技术标签:

【中文标题】如何在 Kotlin 中保存延迟帖子的状态【英文标题】:How to save the state of delayed posts in Kotlin 【发布时间】:2019-12-07 00:31:59 【问题描述】:

对于 android 应用,我想延迟显示一些内容。因此,我正在使用处理程序。

private lateinit var mHandler: Handler

override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    linearLayout.isVisible = false

    mHandler = Handler()
    mHandler.postDelayed(
        linearLayout.isVisible = true 
    , 1000)

如何保存此状态(例如在旋转应用的情况下)?使用SharedPreferences 或类似的东西更好吗:

override fun onSaveInstanceState(outState: Bundle?) 
    super.onSaveInstanceState(outState)



override fun onRestoreInstanceState(savedInstanceState: Bundle?) 
    super.onRestoreInstanceState(savedInstanceState)


【问题讨论】:

视情况而定。如果您只想保留旋转状态,savedInstanceState 很好。但是如果这个状态只是一个时间状态并且对于连续的应用程序启动你想要保留状态,去共享首选项。 如果您想“无限期地”保存非常小的数据,请使用共享首选项,否则请寻找其他方式,包括onSaveInstance() 对于 tasks(相对于 state),在轮换中“保存”它们的推荐方法是使用保留片段:@987654321 @(是的,六年后仍然如此)。 Android 架构组件为此使用 ViewModel:developer.android.com/reference/android/arch/lifecycle/… ... 这些只是底层保留的片段! 【参考方案1】:

我建议使用较新的ViewModel 组件来解决此类问题。 ViewModel 不会像活动和片段那样在配置更改时被破坏,因此您可以运行 Handler(或 Timer)而不必担心丢失其状态。

class MainViewModel : ViewModel() 
    private val layoutVisibility: MutableLiveData<Boolean> by lazy 
        MutableLiveData().also 
            delayVisibility()
        
    

    private fun delayVisibility() 
        Timer().schedule(1000) 
            layoutVisibility.postValue(true)
        
    


class MainActivity : AppCompatActivity() 
    private lateinit var model: MainViewModel

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        model = ViewModelProviders.of(this)[MainViewModel::class.java]

        linearLayout.isVisible = false

        model.layoutVisibility.observe(this, Observer<Boolean>  visibility ->
            linearLayout.isVisible = visibility == true
        )
    


可以保存处理程序的状态——通过保存开始时间并计算重新创建活动时已经过去了多少时间——但ViewModel 架构对我来说似乎更直观。

class MainActivity : AppCompatActivity() 
    private lateinit var startTime: Long

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        linearLayout.isVisible = false

        var elapsedTime: Long = 0L    
        if (savedInstanceState != null) 
            startTime = savedInstanceState.getLong(KEY_START_TIME, System.currentTimeMillis())
            elapsedTime = System.currentTimeMillis() - startTime
         else 
            startTime = System.currentTimeMillis()
        

        if (elapsedTime >= 1000) 
            linearLayout.isVisible = true
         else 
            Handler().postDelayed(
                linearLayout.isVisible = true
            , 1000 - elapsedTime)
        
    

    override fun onSaveInstanceState(outState: Bundle) 
        super.onSaveInstanceState(outState)
        outState.putLong(KEY_START_TIME, startTime)
    

    companion object 
        private const val KEY_START_TIME = "start_time"
    

【讨论】:

谢谢!我试过ViewModel,效果很好!只需对我的 build.gradle 实现这两个依赖项:implementation "android.arch.lifecycle:extensions:1.1.1"implementation "android.arch.lifecycle:viewmodel:1.1.1" :)

以上是关于如何在 Kotlin 中保存延迟帖子的状态的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 popUpToSaveState 和 restoreState 在导航组件 Android Kotlin 中保存和保持状态?

如何在 Kotlin Multiplatform(纯 kotlin)中进行延迟

Qt:如何在 QTimer 处于活动状态时延迟程序?

Kotlin 协程 - 延迟,它是如何工作的?

Kotlin延迟后如何调用函数?

如何在 Kotlin 的卡片视图中设置属性