编写Activity时遇到的一个问题,在此记录,也分享下,Activity写好运行后,genimotion开启应用,却发现界面不显示内容,后来发现标题栏label也不显示。于是开始排查问题原因,在确认setContentView调用,布局文件填充、编写无误,as没有问题情况下,gradle没有问题下,因为gradle编译其他应用正常,依然不显示,奇怪了,不过还是要继续找问题出在哪儿。
最终问题出现在onCreate方法,是不是很惊讶,的确,压根没想到onCreate方法会出什么问题。
到底出什么问题呢,发现,Activity的Context中有两个onCreate方法,具体如下:
android 5.0 (即android 4.4w,API level是android 20)之前的Activity源码:
protected void onCreate(Bundle savedInstanceState){
//...
}
final void performCreate(Bundle icicle) {
onCreate(icicle);
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
//....
}
protected void onSaveInstanceState(Bundle outState) {
//...
}
android 5.0(包含android 5.0,API level是android 21)以后Activity源码:
protected void onCreate(@Nullable Bundle savedInstanceState) {
//...
}
public void onCreate(@Nullable Bundle savedInstanceState,@Nullable PersistableBundle persistentState) {
onCreate(savedInstanceState);
}
final void performCreate(Bundle icicle) {
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
onCreate(icicle, persistentState);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
final void performCreateCommon() {
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}
<pre name="code" class="java"> protected void onSaveInstanceState(Bundle outState) {
//...
}
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {onSaveInstanceState(outState);
}
<pre name="code" class="java"> protected void onRestoreInstanceState(Bundle savedInstanceState) {
//....
}
public void onRestoreInstanceState(Bundle savedInstanceState,PersistableBundle persistentState) {
if (savedInstanceState != null) {
onRestoreInstanceState(savedInstanceState);
}
}
对比看出:
android 5.0之后,在原有的onCreate方法上,重载出新onCreate方法,该方法是public修饰,带有两个参数,Bundle、PersistableBundle,重载后的onCreate方法里调用了原有的onCreate方法
android 5.0之后,在原有performCreate方法上,重载新performCreate方法,并带有两个参数,Bundle、PersistableBundle,方法内部分别对应调用onCreate的方法
android 5.0之后,将原有performCreate部分代码抽取,新增方法performCreateCommon
android 5.0之后,onSaveInstanceState,onRestoreInstanceState同样进行重载
原有onCreate方法,是这么描述:
当Activity启动的时候,会调用该方法,方法内填充界面内容,初始化控件,初始化数据等
重载的onCreate方法,是这么描述:
跟原有onCreate相同,但是调用该方法的Activity比较特别,这些Activity必须是android.R.attr下的persistableMode模式,并且设置为persistAcrossReboots
在Manifest中的activity设置属性:
android:persistableMode="persistAcrossReboots"
这里有个疑问,是不是将Activity的persistMode配置成persistAcrossReboots,就会在启动Activity时,调用带有PersistableBundle的onCreate方法呢?
配置persistMode配置成persistAcrossReboots,重写onCreate(Bundle icicle, PersistableBundle persistentState) ,加载布局,初始化控件,结果,界面不显示
不配置persistMode,重写onStart(Bundle icicle),加载布局,初始化控件,结果,界面显示
结论:一般情况下,Activity的创建,重写的是onStart(Bundle icicle),而非onCreate(Bundle icicle, PersistableBundle persistentState),正常启动Activity,是不会调用后者的,即便后者内部写了加载布局,初始化控件等这些代码,也不会执行