在前面幾期學(xué)習(xí)了Activity的創(chuàng)建、配置拳喻、啟動(dòng)和停止哭当,還學(xué)了Activity的生命周期,本期一起來(lái)學(xué)習(xí)Activity有關(guān)的更多事兒冗澈。
一钦勘、數(shù)據(jù)保存
通過(guò)上一期 LogCat 窗口打印的日志可以看出,當(dāng) Activity失去焦點(diǎn)時(shí)亚亲,首先必然會(huì)執(zhí)行onPause()方法彻采,因此當(dāng)項(xiàng)目中需要保存數(shù)據(jù)時(shí),可以在onPause()方法中保存捌归。同時(shí)肛响,當(dāng)兩個(gè)Activity跳轉(zhuǎn)時(shí), MainActivity會(huì)先失去焦點(diǎn)讓SecondActivity得到焦點(diǎn)惜索,等到SecondActivity完全顯示在前臺(tái)時(shí)MainActivity才會(huì)切換到后臺(tái)特笋。
可能有的同學(xué)已經(jīng)發(fā)現(xiàn),在 Activity的生命周期方法中巾兆,只有第一個(gè) onCreate()回調(diào)方法帶有參數(shù) savedInstanceState猎物,其他回調(diào)方法都是沒有參數(shù)的虎囚,這個(gè)參數(shù)有什么作用呢?
經(jīng)常會(huì)出現(xiàn)用戶按到 HOME鍵退出了界面蔫磨,或者安卓系統(tǒng)意外回收了應(yīng)用溜宽,這種情況下,使用 savedInstanceState就可以讓用戶再次打開應(yīng)用時(shí)恢復(fù)原來(lái)的狀態(tài)质帅。
在具體學(xué)習(xí)savedInstanceState之前,先來(lái)了解一下onSaveInstanceState() 和 onRestoreInstanceState() 方法留攒,這兩個(gè)方法并不是Activity的生命周期方法煤惩,它們不同于 onCreate()、onPause()等生命周期方法炼邀,它們并不一定會(huì)被回調(diào)魄揉。當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足、用戶直接按HOME鍵)由系統(tǒng)銷毀一個(gè)Activity時(shí)拭宁,onSaveInstanceState() 會(huì)被調(diào)用洛退;但是當(dāng)用戶主動(dòng)去銷毀一個(gè)Activity時(shí)(如在應(yīng)用中按返回鍵),onSaveInstanceState()就不會(huì)被調(diào)用杰标。因?yàn)樵谶@種情況下兵怯,用戶的行為決定了不需要保存Activity的狀態(tài)。通常onSaveInstanceState()只適合用于保存一些臨時(shí)性的狀態(tài)腔剂,而onPause()適合用于數(shù)據(jù)的持久化保存媒区。
在Activity被殺掉之前調(diào)用保存每個(gè)實(shí)例的狀態(tài),以保證該狀態(tài)可以在onCreate(Bundle)或者onRestoreInstanceState(Bundle) (傳入的Bundle參數(shù)是由onSaveInstanceState封裝好的)中恢復(fù)掸犬。這個(gè)方法在一個(gè)Activity被殺死前調(diào)用袜漩,當(dāng)該Activity在將來(lái)某個(gè)時(shí)刻回來(lái)時(shí)可以恢復(fù)其先前狀態(tài)。 例如湾碎,如果Activity B啟用后位于Activity A的前端宙攻,在某個(gè)時(shí)刻Activity A因?yàn)橄到y(tǒng)回收資源的問(wèn)題要被殺掉,A通過(guò)onSaveInstanceState將有機(jī)會(huì)保存其用戶界面狀態(tài)介褥,使得將來(lái)用戶返回到Activity A時(shí)能通過(guò)onCreate(Bundle)或者onRestoreInstanceState(Bundle)恢復(fù)界面的狀態(tài)座掘。
onSaveInstanceState()方法會(huì)在什么時(shí)候被執(zhí)行,有這么幾種情況:
當(dāng)用戶按下HOME鍵時(shí)呻顽。
長(zhǎng)按HOME鍵雹顺,選擇運(yùn)行其他的程序時(shí)。
按下電源按鍵(關(guān)閉屏幕顯示)時(shí)廊遍。
從Activity A中啟動(dòng)一個(gè)新的Activity時(shí)嬉愧。
屏幕方向切換時(shí),例如從豎屏切換到橫屏?xí)r喉前。
總而言之没酣,onSaveInstanceState()的調(diào)用遵循一個(gè)重要原則王财,即當(dāng)系統(tǒng)存在“未經(jīng)你許可”時(shí)銷毀了我們的Activity的可能時(shí),則onSaveInstanceState()會(huì)被系統(tǒng)調(diào)用裕便,這是系統(tǒng)的責(zé)任绒净,因?yàn)樗仨氁峁┮粋€(gè)機(jī)會(huì)讓你保存你的數(shù)據(jù)。
onRestoreInstanceState()方法一般是在onStart()和onResume()之間執(zhí)行偿衰。其被調(diào)用的前提是挂疆,Activity A確實(shí)被系統(tǒng)銷毀了,而如果僅僅是停留在有這種可能性的情況下下翎,則該方法不會(huì)被調(diào)用缤言,例如,當(dāng)正在顯示Activity A的時(shí)候视事,用戶按下HOME鍵回到主界面胆萧,然后用戶緊接著又返回到Activity A,這種情況下Activity A一般不會(huì)因?yàn)閮?nèi)存的原因被系統(tǒng)銷毀俐东,故Activity A的onRestoreInstanceState方法不會(huì)被執(zhí)行跌穗。此也說(shuō)明上二者,大多數(shù)情況下不成對(duì)被使用虏辫。
二蚌吸、橫豎屏切換
關(guān)于橫豎屏切換,這一塊其實(shí)有很多事情砌庄,接下來(lái)一一進(jìn)行學(xué)習(xí)套利。
1、可以橫豎屏切換但禁止銷毀重建
現(xiàn)實(shí)生活中鹤耍,使用手機(jī)時(shí)會(huì)根據(jù)不同情洗進(jìn)行橫豎屏切換肉迫。當(dāng)手機(jī)橫豎屏切換時(shí),Activity會(huì)銷毀重建稿黄。
這里使用上一期Activity生命周期的示例喊衫,當(dāng)程序運(yùn)行時(shí),這時(shí)候切換模擬器或手機(jī)的橫豎屏方向杆怕,可以在LogCat 窗口看到下圖所示的輸出:
從上圖可以看出族购,當(dāng)橫豎屏切換時(shí)Activity會(huì)依次回調(diào)onPause()、onStop()陵珍、 onDestory()寝杖、onCreate()、onStar()互纯、onResume()方法瑟幕。這種情況對(duì)實(shí)際開發(fā)肯定會(huì)有影響,那應(yīng)該如何解決呢?
如果不希望在橫豎屏切換時(shí)Activity被銷毀重建只盹,可以在 AndroidManifest.xml文件中設(shè)置 Activity的android:conflgChanges的屬性辣往,這樣無(wú)論怎樣切換Activity都不會(huì)銷毀重新創(chuàng)建,具體設(shè)置代碼如下所示:
android:configChanges="orientation丨keyboardHidden丨screenSize"
2殖卑、禁止橫豎屏切換
如果希望某一個(gè)界面一直處于豎豎橫屏狀態(tài)站削,不隨手機(jī)的晃動(dòng)而改變,同樣可以在清單文件中通過(guò)設(shè)置Activity的android:screenOrientation屬性來(lái)完成孵稽。該屬性主要有以下幾個(gè)值:
unspecified:默認(rèn)值由系統(tǒng)來(lái)判斷顯示方向许起。判定的策略是和設(shè)備相關(guān)的,不同的設(shè)備會(huì)有不同的顯示方向菩鲜。
landscape:橫屏顯示(寬比高要長(zhǎng))街氢。
portrait:豎屏顯示(高比寬要長(zhǎng))。
user:用戶當(dāng)前首選的方向睦袖。
behind:和該Activity下面的那個(gè)Activity的方向一致(在Activity堆棧中的)。
sensor:有物理的感應(yīng)器來(lái)決定荣刑。如果用戶旋轉(zhuǎn)設(shè)備這屏幕會(huì)橫豎屏切換馅笙。
nosensor:忽略物理感應(yīng)器,這樣就不會(huì)隨著用戶旋轉(zhuǎn)設(shè)備而更改了("unspecified"設(shè)置除外)厉亏。
比如設(shè)置為豎屏并不可切換方向董习,具體設(shè)置代碼如下所示:
android:screenOrieritation="portrait"
除了在配置文件中配置,其實(shí)還可以在Java文件中設(shè)置爱只,只要在onCreate方法中加一句代碼即可皿淋,如保持豎屏代碼為:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
如保持橫屏,代碼為:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
當(dāng)然在實(shí)際開發(fā)中不可能每個(gè)Activity都這樣多加一句恬试,不僅維護(hù)麻煩而且容易出錯(cuò)窝趣。一般都是先定義一個(gè)BaseActivity,讓其繼承Activity训柴,然后重寫onCreate方法哑舒,并進(jìn)行橫豎屏設(shè)置,最后讓其他的Activity繼承BaseActivity即可幻馁。
3洗鸵、橫豎屏切換同時(shí)切換不同布局
在開發(fā)中有時(shí)候希望橫豎屏?xí)r加載不同的布局,可以通過(guò)兩種方式來(lái)實(shí)現(xiàn):
準(zhǔn)備兩套不同的布局仗嗦,Android會(huì)自己根據(jù)橫豎屏加載不同布局膘滨。layout-land為橫屏,layout-port為豎屏稀拐。然后把這兩套布局文件放這兩文件夾里火邓,文件名一樣,Android就會(huì)自行判斷加載相應(yīng)布局。
在Java代碼中進(jìn)行判斷贡翘,自己想加載什么就加載什么蹈矮。一般是在onCreate()方法中加載布局文件,可以對(duì)橫豎屏的狀態(tài)做下判斷鸣驱,關(guān)鍵代碼如下:
if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE){
setContentView(R.layout.橫屏布局);
}elseif(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.豎屏布局);
}
當(dāng)然在橫豎屏切換過(guò)程中泛鸟,可以讓Activity銷毀重建,需要注意的就是相關(guān)數(shù)據(jù)的保存踊东,可以參考前面數(shù)據(jù)保存部分的內(nèi)容北滥,當(dāng)然還可以通過(guò)其他方式來(lái)完成,如數(shù)據(jù)持久化闸翅,后期再逐步來(lái)學(xué)習(xí)再芋。
今天就先到這里,如果有問(wèn)題歡迎留言一起探討坚冀,也歡迎加入Android零基礎(chǔ)入門技術(shù)討論微信群瞭郑,共同成長(zhǎng)为狸!
如果該系列分享對(duì)你有幫助,就動(dòng)動(dòng)手指關(guān)注、點(diǎn)贊剖效、留言吧偷俭,你的互動(dòng)就是對(duì)我最大的鼓勵(lì)她我!
此文章版權(quán)為微信公眾號(hào)分享達(dá)人秀(ShareExpert)——鑫鱻所有枚赡,若需轉(zhuǎn)載請(qǐng)聯(lián)系作者授權(quán),特此聲明滑凉!
往期總結(jié)回顧:
Android零基礎(chǔ)入門第1節(jié):Android的前世今生
Android零基礎(chǔ)入門第2節(jié):Android 系統(tǒng)架構(gòu)和應(yīng)用組件那些事
Android零基礎(chǔ)入門第3節(jié):帶你一起來(lái)聊一聊Android開發(fā)環(huán)境
Android零基礎(chǔ)入門第4節(jié):正確安裝和配置JDK, 高富帥養(yǎng)成第一招
Android零基礎(chǔ)入門第5節(jié):善用ADT Bundle, 輕松邂逅女神
Android零基礎(chǔ)入門第6節(jié):配置優(yōu)化SDK Manager, 正式約會(huì)女神
Android零基礎(chǔ)入門第7節(jié):搞定Android模擬器统扳,開啟甜蜜之旅
Android零基礎(chǔ)入門第8節(jié):HelloWorld,我的第一趟旅程出發(fā)點(diǎn)
Android零基礎(chǔ)入門第9節(jié):Android應(yīng)用實(shí)戰(zhàn)畅姊,不懂代碼也可以開發(fā)
Android零基礎(chǔ)入門第10節(jié):開發(fā)IDE大升級(jí)咒钟,終于迎來(lái)了Android Studio
Android零基礎(chǔ)入門第11節(jié):簡(jiǎn)單幾步帶你飛,運(yùn)行Android Studio工程
Android零基礎(chǔ)入門第12節(jié):熟悉Android Studio界面若未,開始裝逼賣萌
Android零基礎(chǔ)入門第13節(jié):Android Studio個(gè)性化配置盯腌,打造開發(fā)利器
Android零基礎(chǔ)入門第14節(jié):使用高速Genymotion,跨入火箭時(shí)代
Android零基礎(chǔ)入門第15節(jié):掌握Android Studio項(xiàng)目結(jié)構(gòu)陨瘩,揚(yáng)帆起航
Android零基礎(chǔ)入門第16節(jié):Android用戶界面開發(fā)概述
Android零基礎(chǔ)入門第17節(jié):文本框TextView
Android零基礎(chǔ)入門第18節(jié):輸入框EditText
Android零基礎(chǔ)入門第19節(jié):按鈕Button
Android零基礎(chǔ)入門第20節(jié):復(fù)選框CheckBox和單選按鈕RadioButton
Android零基礎(chǔ)入門第21節(jié):開關(guān)組件ToggleButton和Switch
Android零基礎(chǔ)入門第22節(jié):圖像視圖ImageView
Android零基礎(chǔ)入門第23節(jié):圖像按鈕ImageButton和縮放按鈕ZoomButton
Android零基礎(chǔ)入門第24節(jié):自定義View簡(jiǎn)單使用腕够,打造屬于你的控件
Android零基礎(chǔ)入門第25節(jié):簡(jiǎn)單且最常用的LinearLayout線性布局
Android零基礎(chǔ)入門第26節(jié):兩種對(duì)齊方式,layout_gravity和gravity大不同
Android零基礎(chǔ)入門第27節(jié):正確使用padding和margin
Android零基礎(chǔ)入門第28節(jié):輕松掌握RelativeLayout相對(duì)布局
Android零基礎(chǔ)入門第29節(jié):善用TableLayout表格布局
Android零基礎(chǔ)入門第30節(jié):兩分鐘掌握FrameLayout幀布局
Android零基礎(chǔ)入門第31節(jié):少用的AbsoluteLayout絕對(duì)布局
Android零基礎(chǔ)入門第32節(jié):新推出的GridLayout網(wǎng)格布局
Android零基礎(chǔ)入門第33節(jié):Android事件處理概述
Android零基礎(chǔ)入門第34節(jié):Android中基于監(jiān)聽的事件處理
Android零基礎(chǔ)入門第35節(jié):Android中基于回調(diào)的事件處理
Android零基礎(chǔ)入門第36節(jié):Android系統(tǒng)事件的處理
Android零基礎(chǔ)入門第37節(jié):初識(shí)ListView
Android零基礎(chǔ)入門第38節(jié):初識(shí)Adapter
Android零基礎(chǔ)入門第39節(jié):ListActivity和自定義列表項(xiàng)
Android零基礎(chǔ)入門第40節(jié):自定義ArrayAdapter
Android零基礎(chǔ)入門第41節(jié):使用SimpleAdapter
Android零基礎(chǔ)入門第42節(jié):自定義BaseAdapter
Android零基礎(chǔ)入門第43節(jié):ListView優(yōu)化和列表首尾使用
Android零基礎(chǔ)入門第44節(jié):ListView數(shù)據(jù)動(dòng)態(tài)更新
Android零基礎(chǔ)入門第45節(jié):網(wǎng)格視圖GridView
Android零基礎(chǔ)入門第46節(jié):列表選項(xiàng)框Spinner
Android零基礎(chǔ)入門第47節(jié):自動(dòng)完成文本框AutoCompleteTextView
Android零基礎(chǔ)入門第48節(jié):可折疊列表ExpandableListView
Android零基礎(chǔ)入門第49節(jié):AdapterViewFlipper圖片輪播
Android零基礎(chǔ)入門第50節(jié):StackView卡片堆疊
Android零基礎(chǔ)入門第51節(jié):進(jìn)度條ProgressBar
Android零基礎(chǔ)入門第52節(jié):自定義ProgressBar炫酷進(jìn)度條
Android零基礎(chǔ)入門第53節(jié):拖動(dòng)條SeekBar和星級(jí)評(píng)分條RatingBar
Android零基礎(chǔ)入門第54節(jié):視圖切換組件ViewSwitcher
Android零基礎(chǔ)入門第55節(jié):ImageSwitcher和TextSwitcher
Android零基礎(chǔ)入門第56節(jié):翻轉(zhuǎn)視圖ViewFlipper
Android零基礎(chǔ)入門第57節(jié):DatePicker和TimePicker選擇器
Android零基礎(chǔ)入門第58節(jié):數(shù)值選擇器NumberPicker
Android零基礎(chǔ)入門第59節(jié):常用三大Clock時(shí)鐘組件
Android零基礎(chǔ)入門第60節(jié):日歷視圖CalendarView和定時(shí)器Chronometer
Android零基礎(chǔ)入門第61節(jié):滾動(dòng)視圖ScrollView
Android零基礎(chǔ)入門第62節(jié):搜索框組件SearchView
Android零基礎(chǔ)入門第63節(jié):值得借鑒學(xué)習(xí)的選項(xiàng)卡TabHost
Android零基礎(chǔ)入門第64節(jié):揭開RecyclerView廬山真面目
Android零基礎(chǔ)入門第65節(jié):RecyclerView分割線開發(fā)技巧
Android零基礎(chǔ)入門第66節(jié):RecyclerView點(diǎn)擊事件處理
Android零基礎(chǔ)入門第67節(jié):RecyclerView數(shù)據(jù)動(dòng)態(tài)更新
Android零基礎(chǔ)入門第68節(jié):RecyclerView添加首尾視圖
Android零基礎(chǔ)入門第69節(jié):ViewPager快速實(shí)現(xiàn)引導(dǎo)頁(yè)
Android零基礎(chǔ)入門第70節(jié):ViewPager打造TabHost效果
Android零基礎(chǔ)入門第71節(jié):CardView簡(jiǎn)單實(shí)現(xiàn)卡片式布局
Android零基礎(chǔ)入門第72節(jié):SwipeRefreshLayout下拉刷新
Android零基礎(chǔ)入門第73節(jié):Activity創(chuàng)建和配置
Android零基礎(chǔ)入門第74節(jié):Activity啟動(dòng)和關(guān)閉
Android零基礎(chǔ)入門第75節(jié):Activity狀態(tài)和生命周期