編輯:關於Android編程
當屏幕轉動切換的時候 Android 機制是:
銷毀當前屏幕的 Activity ,然後重新開啟一個新的適應屏幕改變的 Activity 。
那麼,我們該如何在屏幕切換的時候頁面信息不被重置呢?
解決實現:
1.在 AnroidMainifest.xml 的 activity 元素中加入:
復制代碼 代碼如下:
android:configChanges="orientation|keyboardHidden"
或
復制代碼 代碼如下:
android:configChanges="orientation|keyboard|keyboardHidden"
表示在改變屏幕方向、彈出軟件盤和隱藏軟鍵盤時,不再去執行 onCreate() 方法,
而是直接執行 onConfigurationChanged() 。
如果不申明此段代碼,按照Activity的生命周期,都會去執行一次 onCreate() 方法,
而 onCreate() 方法通常會在顯示之前做一些初始化工作。
所以如果改變屏幕方向這樣的操作都去執行 onCreate() 方法,就有可能造成重復的初始化,
降低程序效率是必然的了,而且更有可能因為重復的初始化而導致數據的丟失。
這是需要避免的!
2.權限聲明:
復制代碼 代碼如下:
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"></uses-permission>
API 中說該權限允許我們改變配置信息,但是我們在改變屏幕方向的程序中卻並沒有用到該權限,是不是相互沖突了呢?
這裡我們可以這樣認為,當我們聲明該權限的的時候,
系統允許我們通過重寫 activity 中的 onConfigurationChanged 方法來捕獲和修改某些配置信息。
3.在 Java 源代碼文件中重寫 Activity 中的 onConfigurationChanged 方法:
復制代碼 代碼如下:
import android.content.res.Configuration;
// 框架回調函數 onConfigurationChanged 出自 android.content.res.Configuration 包。
// 參數 newConfig - 新設備的配備。
// 當設備配置信息有改動(比如屏幕方向的改變,實體鍵盤的推開或合上等)時,
// 並且如果此時有 Activity 正在運行,系統會調用這個函數。
// 注意:onConfigurationChanged 只會響應應用程序在 AnroidMainifest.xml 中
// 通過 android:configChanges="配置類型" 指定的配置類型的改動;
// 而對於其他配置的更改,則系統會先銷毀當前屏幕的 Activity ,
// 然後重新開啟一個新的適應屏幕改變的 Activity 實例。
public void
onConfigurationChanged( Configuration newConfig )
{
// 一定要先調用父類的同名函數,讓框架默認函數先處理
// 下面這句一定不能省去,否則將引發:android.app.SuperNotCalledException 異常。
super.onConfigurationChanged( newConfig );
// 檢測屏幕的方向:縱向或橫向
if ( this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE )
{
// 當前為橫屏, 在此處添加額外的處理代碼
}
else if ( this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT )
{
//當前為豎屏, 在此處添加額外的處理代碼
}
//檢測實體鍵盤的狀態:推出或者合上
if ( newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO )
{
// 實體鍵盤處於推出狀態,在此處添加額外的處理代碼
}
else if ( newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES )
{
// 實體鍵盤處於合上狀態,在此處添加額外的處理代碼
}
}
一、新建一個 Activity ,並把各個生命周期打印出來:
第一步:
運行 Activity ,得到如下信息:
復制代碼 代碼如下:
onCreate
onStart
onResume
第二步:
按 crtl + f12 切換成橫屏時:
復制代碼 代碼如下:
onSaveInstanceState
onPause
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume
第三步:
再按 crtl + f12 切換成豎屏時,發現打印了兩次相同的信息:
復制代碼 代碼如下:
onSaveInstanceState
onPause
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume
onSaveInstanceState
onPause
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume
第四步:
修改 AndroidManifest.xml 文件中的 Activity 元素,
添加 android:configChanges="orientation" ,
按 crtl + f12 切換成橫屏時:(與上面無修改時相同)
復制代碼 代碼如下:
onSaveInstanceState
onPause
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume
第五步:
再按 crtl + f12 切換成豎屏時,
發現不會再打印相同信息,
但多打印了一行 onConfigChanged :
復制代碼 代碼如下:
onSaveInstanceState
onPause
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume
onConfigurationChanged
第六步:
修改 AndroidManifest.xml 文件中的 Activity 元素,
把
復制代碼 代碼如下:
android:configChanges="orientation"
改成
復制代碼 代碼如下:
android:configChanges="orientation|keyboardHidden"
按 crtl + f12 切換成橫屏時,
就只打印 onConfigChanged :
復制代碼 代碼如下:
onConfigurationChanged
第七步:
按 crtl + f12 切換成豎屏時:
復制代碼 代碼如下:
onConfigurationChanged
onConfigurationChanged
二、總結:
1.不設置 AndroidManifest.xml 文件中的 Activity 元素的 android:configChanges 時,
切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次;
2.設置了 AndroidManifest.xml 文件中的 Activity 元素的
android:configChanges="orientation"時,
切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次;
3.設置了 AndroidManifest.xml 文件中的 Activity 元素的
android:configChanges="orientation|keyboardHidden"時,
切屏不會重新調用各個生命周期,只會執行 onConfigurationChanged 方法!
三、補充一點:
1.當前 Activity 產生事件彈出 Toast 和 AlertDialog 的時候 Activity 的生命周期不會有改變!
2.Activity 運行時按下 home 鍵(跟被完全覆蓋是一樣的):
復制代碼 代碼如下:
onSaveInstanceState --> onPause --> onStop
onRestart --> onStart --> onResume
3.Activity 未被完全覆蓋只是失去焦點:
復制代碼 代碼如下:
onPause --> onResume
本文實例講述了Android利用Intent實現數據傳遞的方法。分享給大家供大家參考,具體如下:在Android開發過程中,很多人都熟悉Intent,這是個用於在多個Vi
實現思路利用自定義的HorizontalScrollView實現。 HorizontalScrollView中管理兩個視圖,一個視圖為“菜單”,另
知識點今天繼續昨天沒有講完的Menu的學習,主要是Popup Menu的學習。Popup Menu(彈出式菜單)彈出式菜單是一種固定在View上的菜單模型。主要用於以下三
本文把runtime的官方文檔給大家翻譯過來,官方文檔的語言比較晦澀難懂,但是我們還是要在正式學習之前閱讀以下,有些名詞不懂不要緊哦,接著往下讀。前言OC是一種面向對象的