Activity界面内容不显示,你遇到了吗?

编写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,是不会调用后者的,即便后者内部写了加载布局,初始化控件等这些代码,也不会执行


发布了41 篇原创文章 · 获赞 18 · 访问量 12万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章