”Activity onCreate方法内代码不执行“问题解决

2,363 阅读2分钟

“onCreate方法内代码不执行”问题解决方法

问题代码:

class MainActivity : AppCompatActivity(R.layout.activity_main) {
    override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
        super.onCreate(savedInstanceState, persistentState)
        // 业务代码
    }
}

正常代码:

class MainActivity : AppCompatActivity(R.layout.activity_main) {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState, persistentState)
        // 业务代码
    }
}

看似只用了不一样的重构方法,但是上面的代码中的业务代码完全无效。 之前完全没有在意过onCreate()方法,这次着实被坑了不少时间,所以我打算好好去研究一下这问题并记录下来,希望也能给你点启发。

探一探究竟

话不多说,我们直接追到Activity.java中去看一下onCreate()。

public void onCreate(@Nullable Bundle savedInstanceState,
            @Nullable PersistableBundle persistentState) {
        onCreate(savedInstanceState);
        // ...
}
// ...
protected void onCreate(@Nullable Bundle savedInstanceState) {
    //...
}

啊这,onCreate (savedInstanceState, persistentState)里面不就直接调用的是onCreate(savedInstanceState)吗?! 更离谱的是persistentState这个参数都没用到???(这个下面会说到)

俩个onCreate方法的区别

根据官方对onCreate (savedInstanceState, persistentState)的解释:

Same as onCreate(android.os.Bundle) but called for those activities created with the attribute R.attr.persistableMode set to persistAcrossReboots.

翻译:onCreate (savedInstanceState, persistentState)和onCreate (savedInstanceState)是一样的,不过调用了onCreate (savedInstanceState, persistentState)的activity需要设置persistableMode属性为“persistAcrossReboots

也就是需要在AndroidManifest.xml给activity加个属性:

<activity
 android:name=".MainActivity"
 android:persistableMode="persistAcrossReboots"/>

参数 persistentState 的作用

首先这个是api21之后提供的。

我们先来说一下onCreate (savedInstanceState, persistentState)的savedInstanceState参数,这个用的较多。当我们需要旋转屏幕的时候,我们会在这里保存一下数据,防止在旋转之后页面数据丢失用户体验不好。而persistentState是保证了系统关机重启后数据恢复的能力, 这是一种极端的使用场景。再深究就是为什么数据存在这俩种bundle里面不会丢了,不过到此处应该点到为止,下次一定了。

具体如何保存数据,可以在官方文档查这俩个方法(Activity的)。

override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle)
override fun onRestoreInstanceState(savedInstanceState: Bundle?, persistentState: PersistableBundle?)

总结一下

在旋转屏幕之后保持界面状态,除了在savedInstanceState保存,还可以用类似于JetPack的ViewModel的方式,用自身生命周期包括Activity的生命周期的组件来保存必要的数据。