摘要:此時(shí)再次旋轉(zhuǎn)屏幕時(shí),該不會被系統(tǒng)殺死和重建,只會調(diào)用。因此可通過和來判斷是否被重建,并取出數(shù)據(jù)進(jìn)行恢復(fù)。但需要注意的是,在取出數(shù)據(jù)時(shí)一定要先判斷是否為空。只有在進(jìn)程不被掉,正常情況下才會執(zhí)行方法。
目錄介紹
1.0.0.1 說下Activity的生命周期?屏幕旋轉(zhuǎn)時(shí)生命周期?異常條件會調(diào)用什么方法?
1.0.0.2 后臺的Activity被系統(tǒng)回收怎么辦?說一下onSaveInstanceState()和onRestoreInstanceState()方法特點(diǎn)?
1.0.0.3 如何避免配置改變時(shí)Activity重建?優(yōu)先級低的Activity在內(nèi)存不足被回收后怎樣做可以恢復(fù)到銷毀前狀態(tài)?
1.0.0.4 app切換到后臺,當(dāng)前activity會走onDestory方法嗎?一般在onstop方法里做什么?什么情況會導(dǎo)致app會被殺死?
1.0.0.5 Activity的啟動過程是有幾種方式?從桌面launcher上點(diǎn)擊應(yīng)用圖標(biāo)會干啥,調(diào)用startActivty()又會做什么?
1.0.0.6 說下Activity的四種啟動模式?singleTop和singleTask的區(qū)別以及應(yīng)用場景?任務(wù)棧的作用是什么?
1.0.0.7 兩個Activity之間怎么傳遞數(shù)據(jù)?intent和bundle有什么區(qū)別?為什么有了intent還要設(shè)計(jì)bundle?
1.0.0.8 知道哪些Activity啟動模式的標(biāo)記位?flag是干什么用的,什么時(shí)候用到?
1.0.1.0 同一程序不同的Activity是否可以放在不同的Task任務(wù)棧中?
1.0.1.1 介紹一下Service,啟動Service有幾種方式,生命周期是怎樣的?說一下onStartCommand()的作用?service如何殺不死?
1.0.1.2 一個Activty先start一個Service后,再bind時(shí)會回調(diào)什么方法?此時(shí)如何做才能回調(diào)Service的destory()方法?
1.0.1.3 bindService是一個異步的過程嗎?綁定service大概需要經(jīng)歷那些過程?
1.0.1.4 是否能在Service進(jìn)行耗時(shí)操作?如果非要可以怎么做,如何避免service線程卡頓?service里面可以彈土司嗎?
1.0.1.5 Activity如何與Service通信?Service的生命周期與啟動方法有什么區(qū)別?
1.0.2.0 是否了解ActivityManagerService,它發(fā)揮什么作用,說一下AMS啟動流程?
1.0.2.1 Android中哪些事件需要用到廣播?廣播的生命周期是怎樣的?
1.0.2.3 廣播有幾種形式?他們分別有什么特點(diǎn),如何使用廣播?廣播是怎么實(shí)現(xiàn)不同進(jìn)程之間通信的?
1.0.2.8 Fragment與Activity之間是如何傳值的?Fragment與Fragment之間是如何傳值的?
1.0.2.9 Activity創(chuàng)建Fragment的方式是什么?FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別?
1.0.3.0 fragment 特點(diǎn)?說一下Fragment的生命周期?如何解決getActivity為null的異常問題?
1.0.3.1 在fragment中為什么有時(shí)getActivity()會為null?Fragment試圖為什么有的時(shí)候會重疊,怎么產(chǎn)生的,又如何解決?
1.0.3.2 為什么fragment傳遞數(shù)據(jù)不用構(gòu)造方法傳遞?FragmentManager , add 和 replace 有什么區(qū)別?
1.0.3.9 Activitiy啟動流程中performLaunchActivity的作用?
1.0.4.0 Intent是什么?Intent可以傳遞哪些數(shù)據(jù)?傳遞對象的時(shí)候?yàn)槭裁匆獙?shí)例化?
1.0.4.1 mipmap系列中xxxhdpi、xxhdpi、xhdpi、hdpi、mdpi和ldpi存在怎樣的關(guān)系?
1.0.4.2 res目錄和assets目錄的區(qū)別?R文件是如何生成的,主要有什么作用?
1.0.4.3 Context是什么?Context有哪些類型,分別作用是什么?Context下有哪些子類?哪些場景只能用activity上下文?
1.0.4.4 ActivityThread的main()的流程大概是怎么樣的?
1.0.5.0 序列化的方式有哪些?效率對比有何優(yōu)勢?如何做性能上分析的?
1.0.5.9 界面的刷新為什么需16.6ms?畫面的顯示需要哪些步驟?界面保持不變時(shí)還會16.6ms刷新一次屏幕嗎?
1.0.6.0 Android中日志級別有哪幾種?開發(fā)中需要注意什么問題,打印日志源碼分析原理是什么?
好消息博客筆記大匯總【15年10月到至今】,包括Java基礎(chǔ)及深入知識點(diǎn),Android技術(shù)博客,Python學(xué)習(xí)筆記等等,還包括平時(shí)開發(fā)中遇到的bug匯總,當(dāng)然也在工作之余收集了大量的面試題,長期更新維護(hù)并且修正,持續(xù)完善……開源的文件是markdown格式的!同時(shí)也開源了生活博客,從12年起,積累共計(jì)500篇[近100萬字],將會陸續(xù)發(fā)表到網(wǎng)上,轉(zhuǎn)載請注明出處,謝謝!
鏈接地址:https://github.com/yangchong2...
如果覺得好,可以star一下,謝謝!當(dāng)然也歡迎提出建議,萬事起于忽微,量變引起質(zhì)變!所有的筆記將會更新到GitHub上,同時(shí)保持更新,歡迎同行提出或者push不同的看法或者筆記!
1.0.0.1 說下Activity的生命周期?屏幕旋轉(zhuǎn)時(shí)生命周期?異常條件會調(diào)用什么方法?
在Activity的生命周期涉及到七大方法,分別是:
onCreate()表示Activity 正在創(chuàng)建,常做初始化工作,如setContentView界面資源、初始化數(shù)據(jù)
onStart()表示Activity 正在啟動,這時(shí)Activity 可見但不在前臺,無法和用戶交互
onResume()表示Activity 獲得焦點(diǎn),此時(shí)Activity 可見且在前臺并開始活動
onPause()表示Activity 正在停止,可做 數(shù)據(jù)存儲、停止動畫等操作
onStop()表示activity 即將停止,可做稍微重量級回收工作,如取消網(wǎng)絡(luò)連接、注銷廣播接收器等
onDestroy()表示Activity 即將銷毀,常做回收工作、資源釋放
onRestart()表示當(dāng)Activity由后臺切換到前臺,由不可見到可見時(shí)會調(diào)用,表示Activity 重新啟動
屏幕旋轉(zhuǎn)時(shí)生命周期
屏幕旋轉(zhuǎn)時(shí)候,如果不做任何處理,activity會經(jīng)過銷毀到重建的過程。一般這種效果都不是想要的。比如視頻播放器就經(jīng)常會涉及屏幕旋轉(zhuǎn)場景。技術(shù)博客大總結(jié)
第一種情況:當(dāng)前的Activity不銷毀【設(shè)置Activity的android:configChanges="orientation|keyboardHidden|screenSize"時(shí),切屏不會重新調(diào)用各個生命周期,只會執(zhí)行onConfigurationChanged方法】
執(zhí)行該方法
//重寫旋轉(zhuǎn)時(shí)方法,不銷毀activity @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); }
第二種情況:銷毀當(dāng)前的Activity后重建,這種也盡量避免。【不設(shè)置Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個生命周期,默認(rèn)首先銷毀當(dāng)前activity,然后重新加載】
異常條件會調(diào)用什么方法
當(dāng)非人為終止Activity時(shí),比如系統(tǒng)配置發(fā)生改變時(shí)導(dǎo)致Activity被殺死并重新創(chuàng)建、資源內(nèi)存不足導(dǎo)致低優(yōu)先級的Activity被殺死,會調(diào)用 onSavaInstanceState() 來保存狀態(tài)。該方法調(diào)用在onStop之前,但和onPause沒有時(shí)序關(guān)系。
有人會問,onSaveInstanceState()與onPause()的區(qū)別,onSaveInstanceState()適用于對臨時(shí)性狀態(tài)的保存,而onPause()適用于對數(shù)據(jù)的持久化保存。
當(dāng)異常崩潰后App又重啟了,這個時(shí)候會走onRestoreInstanceState()方法,可以在該方法中取出onSaveInstanceState()保存的狀態(tài)數(shù)據(jù)。
什么時(shí)候會引起異常生命周期
資源相關(guān)的系統(tǒng)配置發(fā)生改變或者資源不足:例如屏幕旋轉(zhuǎn),當(dāng)前Activity會銷毀,并且在onStop之前回調(diào)onSaveInstanceState保存數(shù)據(jù),在重新創(chuàng)建Activity的時(shí)候在onStart之后回調(diào)onRestoreInstanceState。其中Bundle數(shù)據(jù)會傳到onCreate(不一定有數(shù)據(jù))和onRestoreInstanceState(一定有數(shù)據(jù))。技術(shù)博客大總結(jié)
防止屏幕旋轉(zhuǎn)的時(shí)候重建,在清單文件中添加配置:android:configChanges="orientation"
1.0.0.2 后臺的Activity被系統(tǒng)回收怎么辦?說一下onSaveInstanceState()和onRestoreInstanceState()方法特點(diǎn)?
后臺的Activity被系統(tǒng)回收怎么辦?
Activity中提供了一個 onSaveInstanceState()回調(diào)方法,這個方法會保證一定在活動被回收之前調(diào)用,可以通過這個方法來解決活動被回收時(shí)臨時(shí)數(shù)據(jù)得不到保存的問題。onSaveInstanceState()方法會攜帶一個Bundle類型的參數(shù),Bundle提供了一系列的方法用于保存數(shù)據(jù),比如可以使用putString()方法保存字符串,使用putInt()方法保存整型數(shù)據(jù)。每個保存方法需要傳入兩個參數(shù),第一個參數(shù)是鍵,用于后面從 Bundle中取值,第二個參數(shù)是真正要保存的內(nèi)容。技術(shù)博客大總結(jié)
說一下onSaveInstanceState()和onRestoreInstanceState()方法特點(diǎn)?
Activity的 onSaveInstanceState()和onRestoreInstanceState()并不是生命周期方法,它們不同于onCreate()、onPause()等生命周期方法,它們并不一定會被觸發(fā)。
//保存數(shù)據(jù) @Override protected void onSaveInstanceState(Bundle outBundle) { super.onSaveInstanceState(outBundle); outBundle.putBoolean("Change", mChange); } //取出數(shù)據(jù) @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); mChange = savedInstanceState.getBoolean("Change"); } //或者在onCreate方法取數(shù)據(jù)也可以 //onCreate()方法其實(shí)也有一個Bundle類型的參數(shù)。這個參數(shù)在一般情況下都是null, //但是當(dāng)活動被系統(tǒng)回收之前有通過 onSaveInstanceState()方法來保存數(shù)據(jù)的話,這個參就會帶有之前所保存的全部數(shù)據(jù) protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { String data = savedInstanceState.getString("data"); } }
什么時(shí)候會觸發(fā)走這兩個方法?
當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足、用戶直接按Home鍵)由系統(tǒng)銷毀一個Activity,onSaveInstanceState() 會被調(diào)用。但是當(dāng)用戶主動去銷毀一個Activity時(shí),例如在應(yīng)用中按返回鍵,onSaveInstanceState()就不會被調(diào)用。除非該activity是被用戶主動銷毀的,通常onSaveInstanceState()只適合用于保存一些臨時(shí)性的狀態(tài),而onPause()適合用于數(shù)據(jù)的持久化保存。
onSaveInstanceState()被執(zhí)行的場景有哪些?
系統(tǒng)不知道你按下HOME后要運(yùn)行多少其他的程序,自然也不知道activityA是否會被銷毀,因此系統(tǒng)都會調(diào)用onSaveInstanceState(),讓用戶有機(jī)會保存某些非永久性的數(shù)據(jù)。以下幾種情況的分析都遵循該原則當(dāng)用戶按下HOME鍵時(shí)
長按HOME鍵,選擇運(yùn)行其他的程序時(shí)
鎖屏?xí)r
從activity A中啟動一個新的activity時(shí)
屏幕方向切換時(shí)
1.0.0.3 如何避免配置改變時(shí)Activity重建?優(yōu)先級低的Activity在內(nèi)存不足被回收后怎樣做可以恢復(fù)到銷毀前狀態(tài)?
如何避免配置改變時(shí)Activity重建
為了避免由于配置改變導(dǎo)致Activity重建,可在AndroidManifest.xml中對應(yīng)的Activity中設(shè)置android:configChanges="orientation|screenSize"。此時(shí)再次旋轉(zhuǎn)屏幕時(shí),該Activity不會被系統(tǒng)殺死和重建,只會調(diào)用onConfigurationChanged。因此,當(dāng)配置程序需要響應(yīng)配置改變,指定configChanges屬性,重寫onConfigurationChanged方法即可。
使用場景,比如視頻播放器橫豎屏切換播放視頻,就需要設(shè)置這種屬性。具體可以看我封裝的視頻播放器庫,地址:https://github.com/yangchong2...
優(yōu)先級低的Activity在內(nèi)存不足被回收后怎樣做可以恢復(fù)到銷毀前狀態(tài)
優(yōu)先級低的Activity在內(nèi)存不足被回收后重新打開會引發(fā)Activity重建。Activity被重新創(chuàng)建時(shí)會調(diào)用onRestoreInstanceState(該方法在onStart之后),并將onSavaInstanceState保存的Bundle對象作為參數(shù)傳到onRestoreInstanceState與onCreate方法。因此可通過onRestoreInstanceState(Bundle savedInstanceState)和onCreate((Bundle savedInstanceState)來判斷Activity是否被重建,并取出數(shù)據(jù)進(jìn)行恢復(fù)。但需要注意的是,在onCreate取出數(shù)據(jù)時(shí)一定要先判斷savedInstanceState是否為空。
如何判斷activity的優(yōu)先級?技術(shù)博客大總結(jié)
除了在棧頂?shù)腶ctivity,其他的activity都有可能在內(nèi)存不足的時(shí)候被系統(tǒng)回收,一個activity越處于棧底,被回收的可能性越大.如果有多個后臺進(jìn)程,在選擇殺死的目標(biāo)時(shí),采用最近最少使用算法(LRU)。
1.0.0.4 app切換到后臺,當(dāng)前activity會走onDestory方法嗎?一般在onstop方法里做什么?什么情況會導(dǎo)致app會被殺死,這時(shí)候會走onDestory嗎?
app切換到后臺,當(dāng)前activity會走onDestory方法嗎?
不會走onDestory方法,會先后走onPause和onStop方法。
一般在onstop方法里做什么?
比如。寫輪播圖的時(shí)候,會在onstop方法里寫上暫停輪播圖無限輪播,在onStart方法中會開啟自動無限輪播。
再比如,寫視頻播放器的時(shí)候,當(dāng)app切換到后臺,則需要停止視頻播放,也是可以在onstop中處理的。關(guān)于視頻播放器,可以看我這個開源項(xiàng)目:視頻播放器
什么情況會導(dǎo)致app會被殺死,這時(shí)候會走onDestory嗎?
系統(tǒng)資源不足,會導(dǎo)致app意外被殺死。應(yīng)用只有在進(jìn)程存活的情況下才會按照正常的生命周期進(jìn)行執(zhí)行,如果進(jìn)程突然被kill掉,相當(dāng)于System.exit(0); 進(jìn)程被殺死,根本不會走(activity,fragment)生命周期。只有在進(jìn)程不被kill掉,正常情況下才會執(zhí)行ondestory()方法。
activity被回收如何恢復(fù)
當(dāng)系統(tǒng)內(nèi)存不足時(shí), activity會被回收,我們其實(shí)可以覆寫onSaveInstanceState()方法。onSaveInstanceState()方法接受一個Bundle類型的參數(shù), 開發(fā)者可以將狀態(tài)數(shù)據(jù)存儲到這個Bundle對象中,這樣即使activity被系統(tǒng)摧毀,當(dāng)用戶重新啟動這個activity而調(diào)用它的onCreate()方法時(shí),上述的Bundle對象會作為實(shí)參傳遞給onCreate()方法,開發(fā)者可以從Bundle對象中取出保存的數(shù)據(jù), 然后利用這些數(shù)據(jù)將activity恢復(fù)到被摧毀之前的狀態(tài)。
1.0.0.5 Activity的啟動過程是有幾種方式?從桌面launcher上點(diǎn)擊應(yīng)用圖標(biāo)會干啥,調(diào)用startActivty()又會做什么?
Activity的啟動過程是怎樣的,有幾種方式?
注意是啟動過程,不是生命周期。技術(shù)博客大總結(jié)
app啟動的過程有兩種情況,第一種是從桌面launcher上點(diǎn)擊相應(yīng)的應(yīng)用圖標(biāo),第二種是在activity中通過調(diào)用startActivity來啟動一個新的activity。
從桌面launcher上點(diǎn)擊應(yīng)用圖標(biāo)會干啥,調(diào)用startActivty()又會做什么?
創(chuàng)建一個新的項(xiàng)目,默認(rèn)的根activity都是MainActivity,而所有的activity都是保存在堆棧中的,啟動一個新的activity就會放在上一個activity上面,而我們從桌面點(diǎn)擊應(yīng)用圖標(biāo)的時(shí)候,由于launcher本身也是一個應(yīng)用,當(dāng)我們點(diǎn)擊圖標(biāo)的時(shí)候,系統(tǒng)就會調(diào)用startActivitySately(),一般情況下,我們所啟動的activity的相關(guān)信息都會保存在intent中,比如action,category等等。
我們在安裝這個應(yīng)用的時(shí)候,系統(tǒng)也會啟動一個PackaManagerService的管理服務(wù),這個管理服務(wù)會對AndroidManifest.xml文件進(jìn)行解析,從而得到應(yīng)用程序中的相關(guān)信息,比如service,activity,Broadcast等等,然后獲得相關(guān)組件的信息。
當(dāng)我們點(diǎn)擊應(yīng)用圖標(biāo)的時(shí)候,就會調(diào)用startActivitySately()方法,而這個方法內(nèi)部則是調(diào)用startActivty(),而startActivity()方法最終還是會調(diào)用startActivityForResult()這個方法。而在startActivityForResult()這個方法。因?yàn)閟tartActivityForResult()方法是有返回結(jié)果的,所以系統(tǒng)就直接給一個-1,就表示不需要結(jié)果返回了。
而startActivityForResult()這個方法實(shí)際是通過Instrumentation類中的execStartActivity()方法來啟動activity,Instrumentation這個類主要作用就是監(jiān)控程序和系統(tǒng)之間的交互。而在這個execStartActivity()方法中會獲取ActivityManagerService的代理對象,通過這個代理對象進(jìn)行啟動activity。啟動會就會調(diào)用一個checkStartActivityResult()方法,如果說沒有在配置清單中配置有這個組件,就會在這個方法中拋出異常了。
當(dāng)然最后是調(diào)用的是Application.scheduleLaunchActivity()進(jìn)行啟動activity,而這個方法中通過獲取得到一個ActivityClientRecord對象,而這個ActivityClientRecord通過handler來進(jìn)行消息的發(fā)送,系統(tǒng)內(nèi)部會將每一個activity組件使用ActivityClientRecord對象來進(jìn)行描述,而ActivityClientRecord對象中保存有一個LoaderApk對象,通過這個對象調(diào)用handleLaunchActivity來啟動activity組件,而頁面的生命周期方法也就是在這個方法中進(jìn)行調(diào)用。
1.0.0.6 說下Activity的四種啟動模式?singleTop和singleTask的區(qū)別以及應(yīng)用場景?任務(wù)棧的作用是什么?
Activity的四種啟動模式
standard標(biāo)準(zhǔn)模式:每次啟動一個Activity就會創(chuàng)建一個新的實(shí)例
singleTop棧頂復(fù)用模式:如果新Activity已經(jīng)位于任務(wù)棧的棧頂,就不會重新創(chuàng)建,并回調(diào) onNewIntent(intent) 方法
singleTask棧內(nèi)復(fù)用模式:只要該Activity在一個任務(wù)棧中存在,都不會重新創(chuàng)建,并回調(diào) onNewIntent(intent) 方法。如果不存在,系統(tǒng)會先尋找是否存在需要的棧,如果不存在該棧,就創(chuàng)建一個任務(wù)棧,并把該Activity放進(jìn)去;如果存在,就會創(chuàng)建到已經(jīng)存在的棧中
singleInstance單實(shí)例模式:具有此模式的Activity只能多帶帶位于一個任務(wù)棧中,且此任務(wù)棧中只有唯一一個實(shí)例
singleTop和singleTask的區(qū)別以及應(yīng)用場景
singleTop:同個Activity實(shí)例在棧中可以有多個,即可能重復(fù)創(chuàng)建;該模式的Activity會默認(rèn)進(jìn)入啟動它所屬的任務(wù)棧,即不會引起任務(wù)棧的變更;為防止快速點(diǎn)擊時(shí)多次startActivity,可以將目標(biāo)Activity設(shè)置為singleTop
singleTask:同個Activity實(shí)例在棧中只有一個,即不存在重復(fù)創(chuàng)建;可通過android:taskAffinity設(shè)定該Activity需要的任務(wù)棧,即可能會引起任務(wù)棧的變更;常用于主頁和登陸頁
singleTop或singleTask的Activity在以下情況會回調(diào)onNewIntent()
singleTop:如果新Activity已經(jīng)位于任務(wù)棧的棧頂,就不會重新創(chuàng)建,并回調(diào) onNewIntent(intent) 方法
singleTask:只要該Activity在一個任務(wù)棧中存在,都不會重新創(chuàng)建,并回調(diào) onNewIntent(intent) 方法
任務(wù)棧的作用是什么?技術(shù)博客大總結(jié)
它是存放 Activity 的引用的,Activity不同的啟動模式,對應(yīng)不同的任務(wù)棧的存放;可通過 getTaskId()來獲取任務(wù)棧的 ID,如果前面的任務(wù)棧已經(jīng)清空,新開的任務(wù)棧ID+1,是自動增長的;首先來看下Task的定義,Google是這樣定義Task的:Task實(shí)際上是一個Activity棧,通常用戶感受的一個Application就是一個Task。從這個定義來看,Task跟Service或者其他Components是沒有任何聯(lián)系的,它只是針對Activity而言的。
1.0.0.7 兩個Activity之間怎么傳遞數(shù)據(jù)?intent和bundle有什么區(qū)別?為什么有了intent還要設(shè)計(jì)bundle?
兩個Activity之間怎么傳遞數(shù)據(jù)?
基本數(shù)據(jù)類型可以通過Intent傳遞數(shù)據(jù)
把數(shù)據(jù)封裝至intent對象中
Intent intent = new Intent(content, MeActivity.class); intent.putExtra("goods_id", goods_id); content.startActivity(intent);
把數(shù)據(jù)封裝至bundle對象中技術(shù)博客大總結(jié)
把bundle對象封裝至intent對象中
Bundle bundle = new Bundle(); bundle.putString("malename", "李志"); intent.putExtras(bundle); startActivity(intent);
intent和bundle有什么區(qū)別?
Intent傳遞數(shù)據(jù)和Bundle傳遞數(shù)據(jù)是一回事,Intent傳遞時(shí)內(nèi)部還是調(diào)用了Bundle。
public @NonNull Intent putExtra(String name, String value) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putString(name, value); return this; }
為什么有了intent還要設(shè)計(jì)bundle?
兩者比較
Bundle只是一個信息的載體,內(nèi)部其實(shí)就是維護(hù)了一個Map
Intent負(fù)責(zé)Activity之間的交互,內(nèi)部是持有一個Bundle的。
bundle使用場景
Fragment之間傳遞數(shù)據(jù);比如,某個Fragment中點(diǎn)擊按鈕彈出一個DialogFragment。最便捷的方式就是通過Fragment.setArguments(args)傳遞參數(shù)。
public static void showFragmentDialog(String title, String content, boolean is_open, AppCompatActivity activity) { ServiceDialogFragment mainDialogFragment = new ServiceDialogFragment(); Bundle bundle = new Bundle(); bundle.putString("title", title); bundle.putString("content", content); bundle.putBoolean("is_open",is_open); mainDialogFragment.setArguments(bundle); mainDialogFragment.show(activity.getSupportFragmentManager()); } @Override public void onCreate(Bundle savedInstanceState) { setLocal(Local.CENTER); super.onCreate(savedInstanceState); Bundle bundle = getArguments(); if (bundle != null) { title = bundle.getString("title"); content = bundle.getString("content"); is_open = bundle.getBoolean("is_open"); } }1.0.0.8 知道哪些Activity啟動模式的標(biāo)記位?flag是干什么用的,什么時(shí)候用到?
常見的標(biāo)記為:
FLAG_ACTIVITY_SINGLE_TOP:對應(yīng)singleTop啟動模式
FLAG_ACTIVITY_NEW_TASK :對應(yīng)singleTask模式
1.0.1.0 同一程序不同的Activity是否可以放在不同的Task任務(wù)棧中?
同一程序不同的Activity是否可以放在不同的Task任務(wù)棧中?
可以的。比如:啟動模式里有個Singleinstance,可以運(yùn)行在另外的多帶帶的任務(wù)棧里面。用這個模式啟動的activity,在內(nèi)存中只有一份,這樣就不會重復(fù)的開啟。
也可以在激活一個新的activity時(shí)候,給intent設(shè)置flag,Intent的flag添加FLAG_ACTIVITY_NEW_TASK,這個被激活的activity就會在新的task棧里面
1.0.1.1 介紹一下Service,啟動Service有幾種方式,生命周期是怎樣的?說一下onStartCommand()的作用?service如何殺不死?
Service分為兩種
本地服務(wù),屬于同一個應(yīng)用程序,通過startService來啟動或者通過bindService來綁定并且獲取代理對象。如果只是想開個服務(wù)在后臺運(yùn)行的話,直接startService即可,如果需要相互之間進(jìn)行傳值或者操作的話,就應(yīng)該通過bindService。
遠(yuǎn)程服務(wù)(不同應(yīng)用程序之間),通過bindService來綁定并且獲取代理對象。
對應(yīng)的生命周期如下:
context.startService() ->onCreate()- >onStartCommand()->Service running--調(diào)用context.stopService() ->onDestroy()
context.bindService()->onCreate()->onBind()->Service running--調(diào)用>onUnbind() -> onDestroy()
注意
Service默認(rèn)是運(yùn)行在main線程的,因此Service中如果需要執(zhí)行耗時(shí)操作(大文件的操作,數(shù)據(jù)庫的拷貝,網(wǎng)絡(luò)請求,文件下載等)的話應(yīng)該在子線程中完成。
Service生命周期解釋技術(shù)博客大總結(jié)
onCreate():服務(wù)第一次被創(chuàng)建時(shí)調(diào)用
onStartComand():服務(wù)啟動時(shí)調(diào)用
onBind():服務(wù)被綁定時(shí)調(diào)用
onUnBind():服務(wù)被解綁時(shí)調(diào)用
onDestroy():服務(wù)停止時(shí)調(diào)用
說一下onStartCommand()的作用?
service如何殺不死?
1.onStartCommand方法,返回START_STICKY(粘性)當(dāng)service因內(nèi)存不足被kill,當(dāng)內(nèi)存又有的時(shí)候,service又被重新創(chuàng)建
2.設(shè)置優(yōu)先級,在服務(wù)里的ondestory里發(fā)送廣播 在廣播里再次開啟這個服務(wù),雙進(jìn)程守護(hù)
1.0.1.2 一個Activty先start一個Service后,再bind時(shí)會回調(diào)什么方法?此時(shí)如何做才能回調(diào)Service的destory()方法?
關(guān)于service中onDestroy()什么時(shí)候會被執(zhí)行?
當(dāng)調(diào)用了startService()方法后,又去調(diào)用stopService()方法,這時(shí)服務(wù)中的onDestroy()方法就會執(zhí)行,表示服務(wù)已經(jīng)銷毀了。
類似地,當(dāng)調(diào)用了 bindService()方法后,又去調(diào)用unbindService()方法,onDestroy()方法也會執(zhí)行,這兩種情況都很好理解。
一個Activty先start一個Service后,再bind時(shí)會回調(diào)什么方法?
先start后bind操作service,此時(shí)如何做才能回調(diào)Service的destory()方法?
完全有可能對一個服務(wù)既調(diào)用了startService()方法,又調(diào)用了bindService()方法的,這種情況下該如何才能讓服務(wù)銷毀掉呢?根據(jù)Android系統(tǒng)的機(jī)制,一個服務(wù)只要被啟動或者被綁定了之后,就會一直處于運(yùn)行狀態(tài),必須要讓以上兩種條件同時(shí)不滿足,服務(wù)才能被銷毀。
這種情況下要同時(shí)調(diào)用stopService()和unbindService()方法,onDestroy()方法才會執(zhí)行這樣就把服務(wù)的生命周期完整地走了一遍。技術(shù)博客大總結(jié)
1.0.1.3 bindService是一個異步的過程嗎?綁定service大概需要經(jīng)歷那些過程? 1.0.1.4 是否能在Service進(jìn)行耗時(shí)操作?如果非要可以怎么做,如何避免service線程卡頓?service里面可以彈土司嗎?
是否能在Service進(jìn)行耗時(shí)操作?
默認(rèn)情況,如果沒有顯示的指定service所運(yùn)行的進(jìn)程,Service和Activity是運(yùn)行在當(dāng)前app所在進(jìn)程的mainThread(UI主線程)里面。
service里面不能執(zhí)行耗時(shí)的操作(網(wǎng)絡(luò)請求,拷貝數(shù)據(jù)庫,大文件),在Service里執(zhí)行耗時(shí)操作,有可能出現(xiàn)主線程被阻塞(ANR)的情況。
如果非要可以怎么做,如何避免service線程卡頓?
需要在子線程中執(zhí)行 new Thread(){}.start();
service里面可以彈土司嗎?
可以,但是有條件。一般很少這樣做……技術(shù)博客大總結(jié)
條件是,service里面彈toast需要添加到主線程里執(zhí)行。
@Override public void onCreate(){ handler = new Handler(Looper.getMainLooper()); System.out.println("service started"); handler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "Test",Toast.LENGTH_SHORT).show(); } }); }1.0.1.5 Activity如何與Service通信?Service的生命周期與啟動方法有什么區(qū)別?
Activity如何與Service通信?
方法一:
添加一個繼承Binder的內(nèi)部類,并添加相應(yīng)的邏輯方法。重寫Service的onBind方法,返回我們剛剛定義的那個內(nèi)部類實(shí)例。Activity中創(chuàng)建一個ServiceConnection的匿名內(nèi)部類,并且重寫里面的onServiceConnected方法和onServiceDisconnected方法,這兩個方法分別會在活動與服務(wù)成功綁定以及解除綁定的時(shí)候調(diào)用,在onServiceConnected方法中,我們可以得到一個剛才那個service的binder對象,通過對這個binder對象進(jìn)行向下轉(zhuǎn)型,得到我們那個自定義的Binder實(shí)例,有了這個實(shí)例,做可以調(diào)用這個實(shí)例里面的具體方法進(jìn)行需要的操作了
方法二
通過BroadCast(廣播)的形式,當(dāng)我們的進(jìn)度發(fā)生變化的時(shí)候我們發(fā)送一條廣播,然后在Activity的注冊廣播接收器,接收到廣播之后更新視圖
1.0.2.0 是否了解ActivityManagerService,它發(fā)揮什么作用,說一下AMS啟動流程?ActivityManagerService是Android中最核心的服務(wù),主要負(fù)責(zé)系統(tǒng)中四大組件的啟動、切換、調(diào)度及應(yīng)用進(jìn)程的管理和調(diào)度等工作,其職責(zé)與操作系統(tǒng)中的進(jìn)程管理和調(diào)度模塊類似。
https://blog.csdn.net/dutedeh...
1.0.2.1 Android中哪些事件需要用到廣播?廣播的生命周期是怎樣的?
Android中哪些事件需要用到廣播?
Android中:系統(tǒng)在運(yùn)行過程中,會產(chǎn)生會多事件,那么某些事件產(chǎn)生時(shí),比如:電量改變、收發(fā)短信、撥打電話、屏幕解鎖、開機(jī),系統(tǒng)會發(fā)送廣播,只要應(yīng)用程序接收到這條廣播,就知道系統(tǒng)發(fā)生了相應(yīng)的事件,從而執(zhí)行相應(yīng)的代碼。使用廣播接收者,就可以收聽廣播
廣播的生命周期是怎樣的?
a.廣播接收者的生命周期非常短暫的,在接收到廣播的時(shí)候創(chuàng)建,onReceive()方法結(jié)束之后銷毀;
b.廣播接收者中不要做一些耗時(shí)的工作,否則會彈出 Application No Response錯誤對話框;
c.最好也不要在廣播接收者中創(chuàng)建子線程做耗時(shí)的工作,因?yàn)閺V播接收者被銷毀后進(jìn)程就成為了空進(jìn)程,很容易被系統(tǒng)殺掉;
d.耗時(shí)的較長的工作最好放在服務(wù)中完成;
1.0.2.3 廣播有幾種形式?他們分別有什么特點(diǎn),如何使用廣播?廣播是怎么實(shí)現(xiàn)不同進(jìn)程之間通信的?
廣播有幾種形式
普通廣播:一種完全異步執(zhí)行的廣播,在廣播發(fā)出之后,所有的廣播接收器幾乎都會在同一時(shí)刻接收到這條廣播消息,因此它們接收的先后是隨機(jī)的。
有序廣播:一種同步執(zhí)行的廣播,在廣播發(fā)出之后,同一時(shí)刻只會有一個廣播接收器能夠收到這條廣播消息,當(dāng)這個廣播接收器中的邏輯執(zhí)行完畢后,廣播才會繼續(xù)傳遞,所以此時(shí)的廣播接收器是有先后順序的,且優(yōu)先級(priority)高的廣播接收器會先收到廣播消息。有序廣播可以被接收器截?cái)嗍沟煤竺娴慕邮掌鳠o法收到它。
本地廣播:發(fā)出的廣播只能夠在應(yīng)用程序的內(nèi)部進(jìn)行傳遞,并且廣播接收器也只能接收本應(yīng)用程序發(fā)出的廣播。
粘性廣播:這種廣播會一直滯留,當(dāng)有匹配該廣播的接收器被注冊后,該接收器就會收到此條廣播。
廣播的兩種注冊形式技術(shù)博客大總結(jié)
廣播的注冊有兩種方法:一種在活動里通過代碼動態(tài)注冊,另一種在配置文件里靜態(tài)注冊。兩種方式的相同點(diǎn)是都完成了對接收器以及它能接收的廣播值這兩個值的定義;不同點(diǎn)是動態(tài)注冊的接收器必須要在程序啟動之后才能接收到廣播,而靜態(tài)注冊的接收器即便程序未啟動也能接收到廣播,比如想接收到手機(jī)開機(jī)完成后系統(tǒng)發(fā)出的廣播就只能用靜態(tài)注冊了。
動態(tài)注冊
需要使用廣播接收者時(shí),執(zhí)行注冊的代碼,不需要時(shí),執(zhí)行解除注冊的代碼。安卓中有一些廣播接收者,必須使用代碼注冊,清單文件注冊是無效的。
public class MainActivity extends Activity { private IntentFilter intentFilter; private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkChangeReceiver = new NetworkChangeReceiver(); registerReceiver(networkChangeReceiver, intentFilter); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(networkChangeReceiver); } class NetworkChangeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "network changes",Toast.LENGTH_SHORT).show(); } } }
靜態(tài)注冊
可以使用清單文件注冊。廣播一旦發(fā)出,系統(tǒng)就會去所有清單文件中尋找,哪個廣播接收者的action和廣播的action是匹配的,如果找到了,就把該廣播接收者的進(jìn)程啟動起來。
1.0.2.8 Fragment與Activity之間是如何傳值的?Fragment與Fragment之間是如何傳值的?
Fragment與Activity之間是如何傳值的?
1.Activity向Fragment傳值:
步驟:
要傳的值,放到bundle對象里;
在Activity中創(chuàng)建該Fragment的對象fragment,通過調(diào)用
fragment.setArguments()傳遞到fragment中;
在該Fragment中通過調(diào)用getArguments()得到bundle對象,就能得到里面的值。
2.Fragment向Activity傳值:
第一種:
在Activity中調(diào)用getFragmentManager()得到fragmentManager,,調(diào)用findFragmentByTag(tag)或者通過findFragmentById(id)
FragmentManager fragmentManager = getFragmentManager();
Fragment fragment = fragmentManager.findFragmentByTag(tag);
第二種:
通過回調(diào)的方式,定義一個接口(可以在Fragment類中定義),接口中有一個空的方法,在fragment中需要的時(shí)候調(diào)用接口的方法,值可以作為參數(shù)放在這個方法中,然后讓Activity實(shí)現(xiàn)這個接口,必然會重寫這個方法,這樣值就傳到了Activity中
Fragment與Fragment之間是如何傳值的?
第一種:
通過findFragmentByTag得到另一個的Fragment的對象,這樣就可以調(diào)用另一個的方法了。
第二種:
通過接口回調(diào)的方式。技術(shù)博客大總結(jié)
第三種:
通過setArguments,getArguments的方式。
1.0.2.9 Activity創(chuàng)建Fragment的方式是什么?FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別?
Activity創(chuàng)建Fragment的方式是什么?
靜態(tài)創(chuàng)建具體步驟
首先我們同樣需要注冊一個xml文件,然后創(chuàng)建與之對應(yīng)的java文件,通過onCreatView()的返回方法進(jìn)行關(guān)聯(lián),最后我們需要在Activity中進(jìn)行配置相關(guān)參數(shù)即在Activity的xml文件中放上fragment的位置。
動態(tài)創(chuàng)建具體步驟
(1)創(chuàng)建待添加的碎片實(shí)例
(2)獲取FragmentManager,在活動中可以直接通過調(diào)用 getSupportFragmentManager()方法得到。
(3)開啟一個事務(wù),通過調(diào)用beginTransaction()方法開啟。
(4)向容器內(nèi)添加或替換碎片,一般使用repalce()方法實(shí)現(xiàn),需要傳入容器的id和待添加的碎片實(shí)例。
(5)提交事務(wù),調(diào)用commit()方法來完成。
FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別?
FragmnetPageAdapter在每次切換頁面時(shí),只是將Fragment進(jìn)行分離,適合頁面較少的Fragment使用以保存一些內(nèi)存,對系統(tǒng)內(nèi)存不會多大影響
FragmentPageStateAdapter在每次切換頁面的時(shí)候,是將Fragment進(jìn)行回收,適合頁面較多的Fragment使用,這樣就不會消耗更多的內(nèi)存
1.0.3.0 fragment 特點(diǎn)?說一下Fragment的生命周期?如何解決getActivity為null的異常問題?
fragment 特點(diǎn)
Fragment可以作為Activity界面的一部分組成出現(xiàn);
可以在一個Activity中同時(shí)出現(xiàn)多個Fragment,并且一個Fragment也可以在多個Activity中使用;
在Activity運(yùn)行過程中,可以添加、移除或者替換Fragment;
Fragment可以響應(yīng)自己的輸入事件,并且有自己的生命周期,它們的生命周期會受宿主Activity的生命周期影響。
Fragment從創(chuàng)建到銷毀整個生命周期中涉及到的方法依次為:
onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()->onPause()->onStop()->onDestroyView()->onDestroy()->onDetach(),其中和Activity有不少名稱相同作用相似的方法,而不同的方法有:
onAttach():當(dāng)Fragment和Activity建立關(guān)聯(lián)時(shí)調(diào)用
onCreateView():當(dāng)Fragment創(chuàng)建視圖時(shí)調(diào)用
onActivityCreated():當(dāng)與Fragment相關(guān)聯(lián)的Activity完成onCreate()之后調(diào)用
onDestroyView():在Fragment中的布局被移除時(shí)調(diào)用
onDetach():當(dāng)Fragment和Activity解除關(guān)聯(lián)時(shí)調(diào)用
如何解決getActivity為null的異常問題技術(shù)博客大總結(jié)
@Override public void onAttach(Context context) { super.onAttach(context); activity = (PhoneNumActivity) context; } @Override public void onDetach() { super.onDetach(); activity = null; }1.0.3.1 在fragment中為什么有時(shí)getActivity()會為null?Fragment試圖為什么有的時(shí)候會重疊,怎么產(chǎn)生的,又如何解決?
getActivity()空指針:
這種情況一般發(fā)生在在異步任務(wù)里調(diào)用getActivity(),而Fragment已經(jīng)onDetach(),此時(shí)就會有空指針,解決方案是在Fragment里使用一個全局變量mActivity,在onAttach()方法里賦值,這樣可能會引起內(nèi)存泄漏,但是異步任務(wù)沒有停止的情況下本身就已經(jīng)可能內(nèi)存泄漏,相比直接crash,這種方式顯得更妥當(dāng)一些。
Fragment視圖重疊:
在類onCreate()的方法加載Fragment,并且沒有判斷saveInstanceState==null或if(findFragmentByTag(mFragmentTag) == null),導(dǎo)致重復(fù)加載了同一個Fragment導(dǎo)致重疊。(PS:replace情況下,如果沒有加入回退棧,則不判斷也不會造成重疊,但建議還是統(tǒng)一判斷下)
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { // 在頁面重啟時(shí),F(xiàn)ragment會被保存恢復(fù),而此時(shí)再加載Fragment會重復(fù)加載,導(dǎo)致重疊 ; if(saveInstanceState == null){ // 或者 if(findFragmentByTag(mFragmentTag) == null) // 正常情況下去 加載根Fragment } }1.0.3.2 為什么fragment傳遞數(shù)據(jù)不用構(gòu)造方法傳遞?FragmentManager , add 和 replace 有什么區(qū)別?
為什么fragment傳遞數(shù)據(jù)不用構(gòu)造方法傳遞?
activity給fragment傳遞數(shù)據(jù)一般不通過fragment的構(gòu)造方法來傳遞,會通過setArguments來傳遞,因?yàn)楫?dāng)橫豎屏?xí){(diào)用fragment的空參構(gòu)造函數(shù),數(shù)據(jù)丟失。
FragmentManager , add 和 replace 有什么區(qū)別?
使用FragmentTransaction的時(shí)候,它提供了這樣兩個方法,一個add,一個replace,add和replace影響的只是界面,而控制回退的,是事務(wù)。
add 是把一個fragment添加到一個容器container里。replace是先remove掉相同id的所有fragment,然后在add當(dāng)前的這個fragment。技術(shù)博客大總結(jié)
在大部分情況下,這兩個的表現(xiàn)基本相同。因?yàn)?,一般,咱們會使用一個FrameLayout來當(dāng)容器,而每個Fragment被add 或者 replace 到這個FrameLayout的時(shí)候,都是顯示在最上層的。所以你看到的界面都是一樣的。但是,使用add的情況下,這個FrameLayout其實(shí)有2層,多層肯定要比一層的來得浪費(fèi),所以還是推薦使用replace。當(dāng)然有時(shí)候還是需要使用add的。比如要實(shí)現(xiàn)輪播圖的效果,每個輪播圖都是一個獨(dú)立的Fragment,而他的容器FrameLayout需要add多個Fragment,這樣他就可以根據(jù)提供的邏輯進(jìn)行輪播了。而至于返回鍵的時(shí)候,這個跟事務(wù)有關(guān),跟使用add還是replace沒有任何關(guān)系。
replace()方法會將被替換掉的那個Fragment徹底地移除掉,因此最好的解決方案就是使用hide()和show()方法來隱藏和顯示Fragment,這就不會讓Fragment的生命周期重走一遍了。
1.0.3.9 Activitiy啟動流程中performLaunchActivity的作用?Activity啟動流程中handleResumeActivity的作用?
Activitiy啟動流程中performLaunchActivity的作用?
從ActivityClientRecord中獲取到待啟動的Activity的組件信息
使用類加載器創(chuàng)建Activity對象
通過LoadedApk的方法創(chuàng)建Applicayiton對象,該對象唯一,不會重復(fù)創(chuàng)建。
會創(chuàng)建ContextImpl并且建立Context和Activity的聯(lián)系,以及創(chuàng)建PhoneWindow,建立Window和Activity的聯(lián)系。
調(diào)用Activity的onCreate()
Activity啟動流程中handleResumeActivity的作用?
執(zhí)行onStart()、onResume()—利用Instrucmentation
獲取Window
創(chuàng)建DecorView、設(shè)置為不可見INVISIBLE、建立DecorView和Activity的聯(lián)系。
獲取Activity的WindowManager
調(diào)用WindowManager.addView(decorView, ...)將DecorView添加到WM中,完成顯示的工作。
何時(shí)將DecorView設(shè)置為VISIBLE?并且顯示出來?技術(shù)博客大總結(jié)
也是在handleResumeActivity中
現(xiàn)將DecorView設(shè)置為不可見
wm.addView(): 將DecorView添加到Window總
然后執(zhí)行makeVisible讓DecorView可見
1.0.4.0 Intent是什么?Intent可以傳遞哪些數(shù)據(jù)?傳遞對象的時(shí)候?yàn)槭裁匆獙?shí)例化?
Intent是一種運(yùn)行時(shí)綁定(run-time binding)機(jī)制,它能在程序運(yùn)行過程中連接兩個不同的組件。
舉例:比如,有一個Activity希望打開網(wǎng)頁瀏覽器查看某一網(wǎng)頁的內(nèi)容,那么這個Activity只需要發(fā)出 WEB_SEARCH_ACTION給Android
Android就會根據(jù)Intent的請求內(nèi)容,查詢各組件注冊時(shí)聲明的 IntentFilter,找到網(wǎng)頁瀏覽器的Activity來瀏覽網(wǎng)頁
Intent可以傳遞的數(shù)據(jù)基本數(shù)據(jù)類型的數(shù)據(jù),數(shù)組,還有集合,還有序列化的對象
序列化:表示將一個對象轉(zhuǎn)換成可存儲或可傳輸?shù)臓顟B(tài)
Android中序列化對象方式:技術(shù)博客大總結(jié)
第一種:JAVA中的Serialize機(jī)制,譯成串行化、序列化……,其作用是能將數(shù)據(jù)對象存入字節(jié)流當(dāng)中,在需要時(shí)重新生成對象。主要應(yīng)用是利用外部存儲設(shè) 備保存對象狀 態(tài),以及通過網(wǎng)絡(luò)傳輸對象等。
第二種:在Android系統(tǒng)中,定位為針對內(nèi)存受限的設(shè)備,因此對性能要求更高,另外系統(tǒng)中采用了新的IPC(進(jìn)程間通信)機(jī)制,必然要求使用性能更出色的對象傳輸方式。
1.0.1.2 Activity如與Service通信?Service的生命周期與啟動方法由什么區(qū)別?可以通過bindService的方式,先在Activity里實(shí)現(xiàn)一個ServiceConnection接口,并將該接口傳遞給bindService()方法,在ServiceConnection接口的onServiceConnected()方法 里執(zhí)行相關(guān)操作。 Service的生命周期與啟動方法由什么區(qū)別? startService():開啟Service,調(diào)用者退出后Service仍然存在。 bindService():開啟Service,調(diào)用者退出后Service也隨即退出。 Service生命周期: 只是用startService()啟動服務(wù):onCreate() -> onStartCommand() -> onDestory 只是用bindService()綁定服務(wù):onCreate() -> onBind() -> onUnBind() -> onDestory 同時(shí)使用startService()啟動服務(wù)與bindService()綁定服務(wù):onCreate() -> onStartCommnad() -> onBind() -> onUnBind() -> onDestory1.1.0.4 廣播有哪些注冊方式?有什么區(qū)別?廣播發(fā)送和接收原理是什么[binder如何運(yùn)作的]?
廣播有哪些注冊方式?
靜態(tài)注冊:常駐系統(tǒng),不受組件生命周期影響,即便應(yīng)用退出,廣播還是可以被接收,耗電、占內(nèi)存。
動態(tài)注冊:非常駐,跟隨組件的生命變化,組件結(jié)束,廣播結(jié)束。在組件結(jié)束前,需要先移除廣播,否則容易造成內(nèi)存泄漏。
廣播發(fā)送和接收原理是什么[binder如何運(yùn)作的]?
繼承BroadcastReceiver,重寫onReceive()方法。
通過Binder機(jī)制向ActivityManagerService注冊廣播。
通過Binder機(jī)制向ActivityMangerService發(fā)送廣播。
ActivityManagerService查找符合相應(yīng)條件的廣播(IntentFilter/Permission)的BroadcastReceiver,將廣播發(fā)送到BroadcastReceiver所在的消息隊(duì)列中。
BroadcastReceiver所在消息隊(duì)列拿到此廣播后,回調(diào)它的onReceive()方法。
1.0.4.1 mipmap系列中xxxhdpi、xxhdpi、xhdpi、hdpi、mdpi和ldpi存在怎樣的關(guān)系?表示不同密度的圖片資源,像素從高到低依次排序?yàn)閤xxhdpi>xxhdpi>xhdpi>hdpi>mdpi>ldpi,根據(jù)手機(jī)的dpi不同加載不同密度的圖片
1.0.4.2 res目錄和assets目錄的區(qū)別?assets:不會在 R文件中生成相應(yīng)標(biāo)記,存放到這里的資源在打包時(shí)會打包到程序安裝包中。(通過 AssetManager 類訪問這些文件)
res:會在 R 文件中生成 id標(biāo)記,資源在打包時(shí)如果使用到則打包到安裝包中,未用到不會打入安裝包中。
res/anim:存放動畫資源
res/raw:和 asset下文件一樣,打包時(shí)直接打入程序安裝包中(會映射到 R文件中)
1.0.4.3 Context是什么?Context有哪些類型,分別作用是什么?Context下有哪些子類?哪些場景只能用activity上下文?
Context是什么?
Context是一個抽象基類。在翻譯為上下文,也可以理解為環(huán)境,是提供一些程序的運(yùn)行環(huán)境基礎(chǔ)信息。
Context有哪些類型,分別作用是什么?
Context下有兩個子類,ContextWrapper是上下文功能的封裝類,而ContextImpl則是上下文功能的實(shí)現(xiàn)類。
ContextWrapper又有三個直接的子類,ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一個帶主題的封裝類,而它有一個直接子類就是Activity,所以Activity和Service以及Application的Context是不一樣的,只有Activity需要主題,Service不需要主題。
Context下有哪些子類,主要是干什么的?
Context一共有三種類型,分別是Application、Activity和Service。
這三個類雖然分別各種承擔(dān)著不同的作用,但它們都屬于Context的一種,而它們具體Context的功能則是由ContextImpl類去實(shí)現(xiàn)的,因此在絕大多數(shù)場景下,Activity、Service和Application這三種類型的Context都是可以通用的。
不過有幾種場景比較特殊,比如啟動Activity,還有彈出Dialog。出于安全原因的考慮,Android是不允許Activity或Dialog憑空出現(xiàn)的,一個Activity的啟動必須要建立在另一個Activity的基礎(chǔ)之上,也就是以此形成的返回棧。而Dialog則必須在一個Activity上面彈出(除非是系統(tǒng)級別吐司),因此在這種場景下,我們只能使用Activity類型的Context,否則將會出錯。
1.0.4.4 ActivityThread的main()的流程大概是怎么樣的?
ActivityThread的main()的流程大概是怎么樣的?
1.0.5.0 序列化的方式有哪些?效率對比有何優(yōu)勢?如何做性能上分析的?
序列化的方式有哪些
Parcelable
Parcelable是Android特有的一個實(shí)現(xiàn)序列化的接口,在Parcel內(nèi)部包裝了可序列化的數(shù)據(jù),可以在Binder中自由傳輸。序列化的功能由writeToParcel方法來完成,最終通過Parcel的一系列write方法完成。反序列化功能由CREAOR來完成,其內(nèi)部標(biāo)明了如何創(chuàng)建序列化對象和數(shù)組,并通過Parcel的一系列read方法來完成反序列化的過程。
Serializable
Serializable是Java提供的一個序列化接口,是一個空接口,用于標(biāo)示對象是否可以支持序列化,通過ObjectOutputStrean及ObjectInputStream實(shí)現(xiàn)序列化和反序列化的過程。注意可以為需要序列化的對象設(shè)置一個serialVersionUID,在反序列化的時(shí)候系統(tǒng)會檢測文件中的serialVersionUID是否與當(dāng)前類的值一致,如果不一致則說明類發(fā)生了修改,反序列化失敗。因此對于可能會修改的類最好指定serialVersionUID的值。
1.0.5.9 界面的刷新為什么需16.6ms?畫面的顯示需要哪些步驟?界面保持不變時(shí)還會16.6ms刷新一次屏幕嗎?
界面的刷新為什么需16.6ms?
系統(tǒng)每16.6ms會發(fā)出一個VSYNC信號,發(fā)出信號后,才會開始進(jìn)行測量、布局和繪制。
發(fā)出VSYNC信號時(shí),還會將此時(shí)顯示器的buffer緩沖區(qū)的數(shù)據(jù)取出,并顯示在屏幕上。
畫面的顯示需要哪些步驟?
CPU計(jì)算數(shù)據(jù)(View樹遍歷并執(zhí)行三大流程:測量、布局和繪制),然后將數(shù)據(jù)交給GPU“
GPU渲染處理,然后將數(shù)據(jù)放到Buffer中。
顯示屏(display)從buffer中取出數(shù)據(jù),并進(jìn)行顯示。
界面保持不變時(shí)還會16.6ms刷新一次屏幕嗎?技術(shù)博客大總結(jié)
對于底層顯示器,每間隔16.6ms接收到VSYNC信號時(shí),就會用buffer中數(shù)據(jù)進(jìn)行一次顯示。所以一定會刷新。
界面刷新的本質(zhì)流程
通過ViewRootImpl的scheduleTraversals()進(jìn)行界面的三大流程。
調(diào)用到scheduleTraversals()時(shí)不會立即執(zhí)行,而是將該操作保存到待執(zhí)行隊(duì)列中。并給底層的刷新信號注冊監(jiān)聽。
當(dāng)VSYNC信號到來時(shí),會從待執(zhí)行隊(duì)列中取出對應(yīng)的scheduleTraversals()操作,并將其加入到主線程的消息隊(duì)列中。
主線程從消息隊(duì)列中取出并執(zhí)行三大流程: onMeasure()-onLayout()-onDraw()
1.0.6.0 Android中日志級別有哪幾種?開發(fā)中需要注意什么問題,打印日志源碼分析原理是什么?
Android中日志級別有哪幾種?
1.Log.v 的輸出顏色為黑色的,輸出大于或等于VERBOSE日志級別的信息,也就是可見級別,一般是最低的信息提示
2.Log.d的輸出顏色是藍(lán)色的,也就是調(diào)式級別,一般不會中止程序,一般是程序員為了調(diào)試而打印的log
3.Log.i的輸出為綠色,輸出大于或等于INFO日志級別的信息,也就是信息界級別,不會中止程序,一般是系統(tǒng)中執(zhí)行操作的信息提示
4.Log.w的輸出為橙色, 輸出大于或等于WARN日志級別的信息,也就是警告級別,一般不會中止程序,但是可能會影響程序執(zhí)行結(jié)果
5.Log.e的輸出為紅色,僅輸出ERROR日志級別的信息,也就是錯誤級別,一般會中止程序運(yùn)行,是最嚴(yán)重的Log級別。
解釋:
verbose
debug調(diào)試
info信息
warn警告
error誤差
通過查看源代碼我們發(fā)現(xiàn)Log類中所有的靜態(tài)日志方法Log.v(),Log.d(),Log.i(),Log.w(),Log.e()等方法都是底層都是調(diào)用了println方法,然后在源碼中查看,其實(shí)其內(nèi)部調(diào)用的是println_native方法,也就是通過JNI調(diào)用底層的c++輸出日志。
關(guān)于其他內(nèi)容介紹 01.關(guān)于博客匯總鏈接1.技術(shù)博客匯總
2.開源項(xiàng)目匯總
3.生活博客匯總
4.喜馬拉雅音頻匯總
5.其他匯總
02.關(guān)于我的博客我的個人站點(diǎn):www.yczbj.org, www.ycbjie.cn
github:https://github.com/yangchong211
知乎:https://www.zhihu.com/people/...
簡書:http://www.jianshu.com/u/b7b2...
csdn:http://my.csdn.net/m0_37700275
喜馬拉雅聽書:http://www.ximalaya.com/zhubo...
開源中國:https://my.oschina.net/zbj161...
泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...
郵箱:yangchong211@163.com
阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault頭條:https://segmentfault.com/u/xi...
掘金:https://juejin.im/user/593943...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/72850.html
摘要:注意,事件分發(fā)是向下傳遞的,也就是父到子的順序。事件分發(fā)機(jī)制的本質(zhì)是要解決,點(diǎn)擊事件由哪個對象發(fā)出,經(jīng)過哪些對象,最終達(dá)到哪個對象并最終得到處理。表示以及分發(fā)給其中在內(nèi)部完成被賦值。會自己處理事件。 目錄介紹 01.Android中事件分發(fā)順序 1.1 事件分發(fā)的對象是誰 1.2 事件分發(fā)的本質(zhì) 1.3 事件在哪些對象間進(jìn)行傳遞 1.4 事件分發(fā)過程涉及方法 1.5 Androi...
閱讀 3728·2023-04-26 01:43
閱讀 3112·2021-10-14 09:42
閱讀 5872·2021-09-30 09:59
閱讀 2244·2021-09-04 16:40
閱讀 1298·2019-08-30 15:52
閱讀 915·2019-08-29 17:09
閱讀 2258·2019-08-26 13:37
閱讀 3622·2019-08-26 10:20