android activity 显示无焦点_Android面试题集锦之fragemnt
大家可以關(guān)注一下小編,小編以后會一直更新Android相關(guān)技術(shù)資料文章。
創(chuàng)建方式
靜態(tài)創(chuàng)建
首先我們需要?jiǎng)?chuàng)建一個(gè)xml文件,然后創(chuàng)建與之對應(yīng)的java文件,通過onCreatView()的返回方法進(jìn)行關(guān)聯(lián),最后我們需要在Activity中進(jìn)行配置相關(guān)參數(shù)即在Activity的xml文件中放上fragment的位置。
動(dòng)態(tài)創(chuàng)建
動(dòng)態(tài)創(chuàng)建Fragment主要有以下幾個(gè)步驟:
創(chuàng)建待添加的fragment實(shí)例。
獲取FragmentManager,在Activity中可以直接通過調(diào)用 getSupportFragmentManager()方法得到。
開啟一個(gè)事務(wù),通過調(diào)用beginTransaction()方法開啟。
向容器內(nèi)添加或替換fragment,一般使用repalce()方法實(shí)現(xiàn),需要傳入容器的id和待添加的fragment實(shí)例。
提交事務(wù),調(diào)用commit()方法來完成。
Adapter對比
FragmnetPageAdapter在每次切換頁面時(shí),只是將Fragment進(jìn)行分離,適合頁面較少的Fragment使用以保存一些內(nèi)存,對系統(tǒng)內(nèi)存不會多大影響。
FragmentPageStateAdapter在每次切換頁面的時(shí)候,是將Fragment進(jìn)行回收,適合頁面較多的Fragment使用,這樣就不會消耗更多的內(nèi)存
Activity生命周期
Activity的生命周期如下圖:
動(dòng)態(tài)加載:
動(dòng)態(tài)加載時(shí),Activity的onCreate()調(diào)用完,才開始加載fragment并調(diào)用其生命周期方法,所以在第一個(gè)生命周期方法onAttach()中便能獲取Activity以及Activity的布局的組件;
靜態(tài)加載:
1.靜態(tài)加載時(shí),Activity的onCreate()調(diào)用過程中,fragment也在加載,所以fragment無法獲取到Activity的布局中的組件,但為什么能獲取到Activity呢?
2.原來在fragment調(diào)用onAttach()之前其實(shí)還調(diào)用了一個(gè)方法onInflate(),該方法被調(diào)用時(shí)fragment已經(jīng)是和Activity相互結(jié)合了,所以可以獲取到對方,但是Activity的onCreate()調(diào)用還未完成,故無法獲取Activity的組件;
3.Activity的onCreate()調(diào)用完成是,fragment會調(diào)用onActivityCreated()生命周期方法,因此在這兒開始便能獲取到Activity的布局的組件;
與Activity通信
fragment不通過構(gòu)造函數(shù)進(jìn)行傳值的原因是因?yàn)闄M屏切換的時(shí)候獲取不到值。
Activity向Fragment傳值:
Activity向Fragment傳值,要傳的值放到bundle對象里;
在Activity中創(chuàng)建該Fragment的對象fragment,通過調(diào)用setArguments()傳遞到fragment中;
在該Fragment中通過調(diào)用getArguments()得到bundle對象,就能得到里面的值。
Fragment向Activity傳值:
第一種:
在Activity中調(diào)用getFragmentManager()得到fragmentManager,,調(diào)用findFragmentByTag(tag)或者通過findFragmentById(id),例如:
FragmentManager fragmentManager = getFragmentManager();Fragment fragment = fragmentManager.findFragmentByTag(tag);第二種:
通過回調(diào)的方式,定義一個(gè)接口(可以在Fragment類中定義),接口中有一個(gè)空的方法,在fragment中需要的時(shí)候調(diào)用接口的方法,值可以作為參數(shù)放在這個(gè)方法中,然后讓Activity實(shí)現(xiàn)這個(gè)接口,必然會重寫這個(gè)方法,這樣值就傳到了Activity中
Fragment與Fragment之間是如何傳值的:
第一種:
通過findFragmentByTag得到另一個(gè)的Fragment的對象,這樣就可以調(diào)用另一個(gè)的方法了。
第二種:
通過接口回調(diào)的方式。
第三種:
通過setArguments,getArguments的方式。
api區(qū)別
add
一種是add方式來進(jìn)行show和add,這種方式你切換fragment不會讓fragment重新刷新,只會調(diào)用onHiddenChanged(boolean isHidden)。
replace
而用replace方式會使fragment重新刷新,因?yàn)閍dd方式是將fragment隱藏了而不是銷毀再創(chuàng)建,replace方式每次都是重新創(chuàng)建。
commit/commitAllowingStateLoss
兩者都可以提交fragment的操作,唯一的不同是第二種方法,允許丟失一些界面的狀態(tài)和信息,幾乎所有的開發(fā)者都遇到過這樣的錯(cuò)誤:無法在activity調(diào)用了onSaveInstanceState之后再執(zhí)行commit(),這種異常時(shí)可以理解的,界面被系統(tǒng)回收(界面已經(jīng)不存在),為了在下次打開的時(shí)候恢復(fù)原來的樣子,系統(tǒng)為我們保存界面的所有狀態(tài),這個(gè)時(shí)候我們再去修改界面理論上肯定是不允許的,所以為了避免這種異常,要使用第二種方法。
懶加載
我們經(jīng)常在使用fragment時(shí),常常會結(jié)合著viewpager使用,那么我們就會遇到一個(gè)問題,就是初始化fragment的時(shí)候,會連同我們寫的網(wǎng)絡(luò)請求一起執(zhí)行,這樣非常消耗性能,最理想的方式是,只有用戶點(diǎn)開或滑動(dòng)到當(dāng)前fragment時(shí),才進(jìn)行請求網(wǎng)絡(luò)的操作。因此,我們就產(chǎn)生了懶加載這樣一個(gè)說法。
Viewpager配合fragment使用,默認(rèn)加載前兩個(gè)fragment。很容易造成網(wǎng)絡(luò)丟包、阻塞等問題。
在Fragment中有一個(gè)setUserVisibleHint這個(gè)方法,而且這個(gè)方法是優(yōu)于onCreate()方法的,它會通過isVisibleToUser告訴我們當(dāng)前Fragment我們是否可見,我們可以在可見的時(shí)候再進(jìn)行網(wǎng)絡(luò)加載。
從log上看setUserVisibleHint()的調(diào)用早于onCreateView,所以如果在setUserVisibleHint()要實(shí)現(xiàn)懶加載的話,就必須要確保View以及其他變量都已經(jīng)初始化結(jié)束,避免空指針。
使用步驟:
申明一個(gè)變量isPrepare=false,isVisible=false,標(biāo)明當(dāng)前頁面是否被創(chuàng)建了
在onViewCreated周期內(nèi)設(shè)置isPrepare=true
在setUserVisibleHint(boolean isVisible)判斷是否顯示,設(shè)置isVisible=true
判斷isPrepare和isVisible,都為true開始加載數(shù)據(jù),然后恢復(fù)isPrepare和isVisible為false,防止重復(fù)加載。
關(guān)于Android Fragment的懶加載,可以參考下面的鏈接:Fragment的懶加載
Activity
Activity啟動(dòng)流程
用戶從Launcher程序點(diǎn)擊應(yīng)用圖標(biāo)可啟動(dòng)應(yīng)用的入口Activity,Activity啟動(dòng)時(shí)需要多個(gè)進(jìn)程之間的交互,Android系統(tǒng)中有一個(gè)zygote進(jìn)程專用于孵化Android框架層和應(yīng)用層程序的進(jìn)程。還有一個(gè)system_server進(jìn)程,該進(jìn)程里運(yùn)行了很多binder service。例如ActivityManagerService,PackageManagerService,WindowManagerService,這些binder service分別運(yùn)行在不同的線程中,其中ActivityManagerService負(fù)責(zé)管理Activity棧,應(yīng)用進(jìn)程,task。
點(diǎn)擊Launcher圖標(biāo)來啟動(dòng)Activity
用戶在Launcher程序里點(diǎn)擊應(yīng)用圖標(biāo)時(shí),會通知ActivityManagerService啟動(dòng)應(yīng)用的入口Activity,ActivityManagerService發(fā)現(xiàn)這個(gè)應(yīng)用還未啟動(dòng),則會通知Zygote進(jìn)程孵化出應(yīng)用進(jìn)程,然后在這個(gè)dalvik應(yīng)用進(jìn)程里執(zhí)行ActivityThread的main方法。應(yīng)用進(jìn)程接下來通知ActivityManagerService應(yīng)用進(jìn)程已啟動(dòng),ActivityManagerService保存應(yīng)用進(jìn)程的一個(gè)代理對象,這樣ActivityManagerService可以通過這個(gè)代理對象控制應(yīng)用進(jìn)程,然后ActivityManagerService通知應(yīng)用進(jìn)程創(chuàng)建入口Activity的實(shí)例,并執(zhí)行它的生命周期方法。
Android繪制流程窗口啟動(dòng)流程分析
Activity生命周期
Activity的形態(tài)
Active/Running:
Activity處于活動(dòng)狀態(tài),此時(shí)Activity處于棧頂,是可見狀態(tài),可與用戶進(jìn)行交互。
Paused:
當(dāng)Activity失去焦點(diǎn)時(shí),或被一個(gè)新的非全屏的Activity,或被一個(gè)透明的Activity放置在棧頂時(shí),Activity就轉(zhuǎn)化為Paused狀態(tài)。但我們需要明白,此時(shí)Activity只是失去了與用戶交互的能力,其所有的狀態(tài)信息及其成員變量都還存在,只有在系統(tǒng)內(nèi)存緊張的情況下,才有可能被系統(tǒng)回收掉。
Stopped:
當(dāng)一個(gè)Activity被另一個(gè)Activity完全覆蓋時(shí),被覆蓋的Activity就會進(jìn)入Stopped狀態(tài),此時(shí)它不再可見,但是跟Paused狀態(tài)一樣保持著其所有狀態(tài)信息及其成員變量。
Killed:
當(dāng)Activity被系統(tǒng)回收掉時(shí),Activity就處于Killed狀態(tài)。
Activity會在以上四種形態(tài)中相互切換,至于如何切換,這因用戶的操作不同而異。了解了Activity的4種形態(tài)后,我們就來聊聊Activity的生命周期。
Activity的生命周期
所謂的典型的生命周期就是在有用戶參與的情況下,Activity經(jīng)歷從創(chuàng)建,運(yùn)行,停止,銷毀等正常的生命周期過程。
onCreate
該方法是在Activity被創(chuàng)建時(shí)回調(diào),它是生命周期第一個(gè)調(diào)用的方法,我們在創(chuàng)建Activity時(shí)一般都需要重寫該方法,然后在該方法中做一些初始化的操作,如通過setContentView設(shè)置界面布局的資源,初始化所需要的組件信息等。
onStart
此方法被回調(diào)時(shí)表示Activity正在啟動(dòng),此時(shí)Activity已處于可見狀態(tài),只是還沒有在前臺顯示,因此無法與用戶進(jìn)行交互。可以簡單理解為Activity已顯示而我們無法看見擺了。
onResume
當(dāng)此方法回調(diào)時(shí),則說明Activity已在前臺可見,可與用戶交互了(處于前面所說的Active/Running形態(tài)),onResume方法與onStart的相同點(diǎn)是兩者都表示Activity可見,只不過onStart回調(diào)時(shí)Activity還是后臺無法與用戶交互,而onResume則已顯示在前臺,可與用戶交互。當(dāng)然從流程圖,我們也可以看出當(dāng)Activity停止后(onPause方法和onStop方法被調(diào)用),重新回到前臺時(shí)也會調(diào)用onResume方法,因此我們也可以在onResume方法中初始化一些資源,比如重新初始化在onPause或者onStop方法中釋放的資源。
onPause
此方法被回調(diào)時(shí)則表示Activity正在停止(Paused形態(tài)),一般情況下onStop方法會緊接著被回調(diào)。但通過流程圖我們還可以看到一種情況是onPause方法執(zhí)行后直接執(zhí)行了onResume方法,這屬于比較極端的現(xiàn)象了,這可能是用戶操作使當(dāng)前Activity退居后臺后又迅速地再回到到當(dāng)前的Activity,此時(shí)onResume方法就會被回調(diào)。當(dāng)然,在onPause方法中我們可以做一些數(shù)據(jù)存儲或者動(dòng)畫停止或者資源回收的操作,但是不能太耗時(shí),因?yàn)檫@可能會影響到新的Activity的顯示——onPause方法執(zhí)行完成后,新Activity的onResume方法才會被執(zhí)行。
onStop
一般在onPause方法執(zhí)行完成直接執(zhí)行,表示Activity即將停止或者完全被覆蓋(Stopped形態(tài)),此時(shí)Activity不可見,僅在后臺運(yùn)行。同樣地,在onStop方法可以做一些資源釋放的操作(不能太耗時(shí))。
onRestart
表示Activity正在重新啟動(dòng),當(dāng)Activity由不可見變?yōu)榭梢姞顟B(tài)時(shí),該方法被回調(diào)。這種情況一般是用戶打開了一個(gè)新的Activity時(shí),當(dāng)前的Activity就會被暫停(onPause和onStop被執(zhí)行了),接著又回到當(dāng)前Activity頁面時(shí),onRestart方法就會被回調(diào)。
onDestroy
此時(shí)Activity正在被銷毀,也是生命周期最后一個(gè)執(zhí)行的方法,一般我們可以在此方法中做一些回收工作和最終的資源釋放。
總結(jié)
當(dāng)Activity啟動(dòng)時(shí),依次會調(diào)用onCreate(),onStart(),onResume(),而當(dāng)Activity退居后臺時(shí)(不可見,點(diǎn)擊Home或者被新的Activity完全覆蓋),onPause()和onStop()會依次被調(diào)用。當(dāng)Activity重新回到前臺(從桌面回到原Activity或者被覆蓋后又回到原Activity)時(shí),onRestart(),onStart(),onResume()會依次被調(diào)用。當(dāng)Activity退出銷毀時(shí)(點(diǎn)擊back鍵),onPause(),onStop(),onDestroy()會依次被調(diào)用,到此Activity的整個(gè)生命周期方法回調(diào)完成。現(xiàn)在我們再回頭看看之前的流程圖,應(yīng)該是相當(dāng)清晰了吧。嗯,這就是Activity整個(gè)典型的生命周期過程。
小編在這里祝福大家都能找到比圖片里還漂亮的小姐姐做老婆
總結(jié)
以上是生活随笔為你收集整理的android activity 显示无焦点_Android面试题集锦之fragemnt的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux搭建邮件服务器(linux 搭
- 下一篇: android 扫描照片功能,Andro