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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章