目錄介紹
- 1.0.0.1 說下Activity的生命周期次酌?屏幕旋轉(zhuǎn)時生命周期葫录?異常條件會調(diào)用什么方法挺邀?
- 1.0.0.2 后臺的Activity被系統(tǒng)回收怎么辦蝠嘉?說一下onSaveInstanceState()和onRestoreInstanceState()方法特點?
- 1.0.0.3 如何避免配置改變時Activity重建荚守?優(yōu)先級低的Activity在內(nèi)存不足被回收后怎樣做可以恢復到銷毀前狀態(tài)珍德?
- 1.0.0.4 app切換到后臺,當前activity會走onDestory方法嗎矗漾?一般在onstop方法里做什么锈候?什么情況會導致app會被殺死?
- 1.0.0.5 Activity的啟動過程是有幾種方式敞贡?從桌面launcher上點擊應用圖標會干啥泵琳,調(diào)用startActivty()又會做什么?
- 1.0.0.6 說下Activity的四種啟動模式誊役?singleTop和singleTask的區(qū)別以及應用場景获列?任務棧的作用是什么?
- 1.0.0.7 兩個Activity之間怎么傳遞數(shù)據(jù)蛔垢?intent和bundle有什么區(qū)別击孩?為什么有了intent還要設計bundle?
- 1.0.0.8 知道哪些Activity啟動模式的標記位啦桌?flag是干什么用的溯壶,什么時候用到?
- 1.0.1.0 同一程序不同的Activity是否可以放在不同的Task任務棧中甫男?
- 1.0.1.1 介紹一下Service且改,啟動Service有幾種方式,生命周期是怎樣的板驳?說一下onStartCommand()的作用又跛?service如何殺不死?
- 1.0.1.2 一個Activty先start一個Service后若治,再bind時會回調(diào)什么方法慨蓝?此時如何做才能回調(diào)Service的destory()方法?
- 1.0.1.3 bindService是一個異步的過程嗎端幼?綁定service大概需要經(jīng)歷那些過程礼烈?
- 1.0.1.4 是否能在Service進行耗時操作?如果非要可以怎么做婆跑,如何避免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 廣播有幾種形式搀庶?他們分別有什么特點,如何使用廣播疯淫?廣播是怎么實現(xià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 特點币绩?說一下Fragment的生命周期蜡秽?如何解決getActivity為null的異常問題?
- 1.0.3.1 在fragment中為什么有時getActivity()會為null缆镣?Fragment試圖為什么有的時候會重疊芽突,怎么產(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ù)挟秤?傳遞對象的時候為什么要實例化壹哺?
- 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捏浊?畫面的顯示需要哪些步驟?界面保持不變時還會16.6ms刷新一次屏幕嗎撞叨?
- 1.0.6.0 Android中日志級別有哪幾種金踪?開發(fā)中需要注意什么問題,打印日志源碼分析原理是什么牵敷?
好消息
- 博客筆記大匯總【15年10月到至今】胡岔,包括Java基礎及深入知識點,Android技術(shù)博客枷餐,Python學習筆記等等靶瘸,還包括平時開發(fā)中遇到的bug匯總,當然也在工作之余收集了大量的面試題毛肋,長期更新維護并且修正怨咪,持續(xù)完善……開源的文件是markdown格式的!同時也開源了生活博客润匙,從12年起诗眨,積累共計500篇[近100萬字],將會陸續(xù)發(fā)表到網(wǎng)上孕讳,轉(zhuǎn)載請注明出處匠楚,謝謝巍膘!
- 鏈接地址:https://github.com/yangchong211/YCBlogs
- 如果覺得好,可以star一下芋簿,謝謝典徘!當然也歡迎提出建議,萬事起于忽微益咬,量變引起質(zhì)變!所有的筆記將會更新到GitHub上帜平,同時保持更新幽告,歡迎同行提出或者push不同的看法或者筆記!
1.0.0.1 說下Activity的生命周期裆甩?屏幕旋轉(zhuǎn)時生命周期冗锁?異常條件會調(diào)用什么方法?
- 在Activity的生命周期涉及到七大方法嗤栓,分別是:
- onCreate()表示Activity 正在創(chuàng)建冻河,常做初始化工作,如setContentView界面資源茉帅、初始化數(shù)據(jù)
- onStart()表示Activity 正在啟動叨叙,這時Activity 可見但不在前臺,無法和用戶交互
- onResume()表示Activity 獲得焦點堪澎,此時Activity 可見且在前臺并開始活動
- onPause()表示Activity 正在停止擂错,可做 數(shù)據(jù)存儲、停止動畫等操作
- onStop()表示activity 即將停止樱蛤,可做稍微重量級回收工作钮呀,如取消網(wǎng)絡連接、注銷廣播接收器等
- onDestroy()表示Activity 即將銷毀昨凡,常做回收工作爽醋、資源釋放
- onRestart()表示當Activity由后臺切換到前臺,由不可見到可見時會調(diào)用便脊,表示Activity 重新啟動
- 屏幕旋轉(zhuǎn)時生命周期
- 屏幕旋轉(zhuǎn)時候蚂四,如果不做任何處理,activity會經(jīng)過銷毀到重建的過程哪痰。一般這種效果都不是想要的证杭。比如視頻播放器就經(jīng)常會涉及屏幕旋轉(zhuǎn)場景。技術(shù)博客大總結(jié)
- 第一種情況:當前的Activity不銷毀【設置Activity的android:configChanges="orientation|keyboardHidden|screenSize"時妒御,切屏不會重新調(diào)用各個生命周期解愤,只會執(zhí)行onConfigurationChanged方法】
<activity
android:name=".activity.VideoDetailActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"/>
//重寫旋轉(zhuǎn)時方法,不銷毀activity
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
- 第二種情況:銷毀當前的Activity后重建乎莉,這種也盡量避免送讲〖轶裕【不設置Activity的android:configChanges時,切屏會重新調(diào)用各個生命周期哼鬓,默認首先銷毀當前activity,然后重新加載】
- 異常條件會調(diào)用什么方法
- 當非人為終止Activity時监右,比如系統(tǒng)配置發(fā)生改變時導致Activity被殺死并重新創(chuàng)建、資源內(nèi)存不足導致低優(yōu)先級的Activity被殺死异希,會調(diào)用 onSavaInstanceState() 來保存狀態(tài)健盒。該方法調(diào)用在onStop之前,但和onPause沒有時序關(guān)系称簿。
- 有人會問扣癣,onSaveInstanceState()與onPause()的區(qū)別,onSaveInstanceState()適用于對臨時性狀態(tài)的保存憨降,而onPause()適用于對數(shù)據(jù)的持久化保存父虑。
- 當異常崩潰后App又重啟了,這個時候會走onRestoreInstanceState()方法授药,可以在該方法中取出onSaveInstanceState()保存的狀態(tài)數(shù)據(jù)士嚎。
- 什么時候會引起異常生命周期
- 資源相關(guān)的系統(tǒng)配置發(fā)生改變或者資源不足:例如屏幕旋轉(zhuǎn),當前Activity會銷毀悔叽,并且在onStop之前回調(diào)onSaveInstanceState保存數(shù)據(jù)莱衩,在重新創(chuàng)建Activity的時候在onStart之后回調(diào)onRestoreInstanceState。其中Bundle數(shù)據(jù)會傳到onCreate(不一定有數(shù)據(jù))和onRestoreInstanceState(一定有數(shù)據(jù))娇澎。技術(shù)博客大總結(jié)
- 防止屏幕旋轉(zhuǎn)的時候重建膳殷,在清單文件中添加配置:android:configChanges="orientation"
1.0.0.2 后臺的Activity被系統(tǒng)回收怎么辦?說一下onSaveInstanceState()和onRestoreInstanceState()方法特點九火?
- 后臺的Activity被系統(tǒng)回收怎么辦赚窃?
- Activity中提供了一個 onSaveInstanceState()回調(diào)方法,這個方法會保證一定在活動被回收之前調(diào)用岔激,可以通過這個方法來解決活動被回收時臨時數(shù)據(jù)得不到保存的問題勒极。onSaveInstanceState()方法會攜帶一個Bundle類型的參數(shù),Bundle提供了一系列的方法用于保存數(shù)據(jù)虑鼎,比如可以使用putString()方法保存字符串辱匿,使用putInt()方法保存整型數(shù)據(jù)。每個保存方法需要傳入兩個參數(shù)炫彩,第一個參數(shù)是鍵匾七,用于后面從 Bundle中取值,第二個參數(shù)是真正要保存的內(nèi)容江兢。技術(shù)博客大總結(jié)
- 說一下onSaveInstanceState()和onRestoreInstanceState()方法特點昨忆?
- 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()方法其實也有一個Bundle類型的參數(shù)。這個參數(shù)在一般情況下都是null拢驾,
//但是當活動被系統(tǒng)回收之前有通過 onSaveInstanceState()方法來保存數(shù)據(jù)的話奖磁,這個參就會帶有之前所保存的全部數(shù)據(jù)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
String data = savedInstanceState.getString("data");
}
}
- 什么時候會觸發(fā)走這兩個方法?
- 當應用遇到意外情況(如:內(nèi)存不足繁疤、用戶直接按Home鍵)由系統(tǒng)銷毀一個Activity瞳氓,onSaveInstanceState() 會被調(diào)用泡嘴。但是當用戶主動去銷毀一個Activity時辣卒,例如在應用中按返回鍵埠偿,onSaveInstanceState()就不會被調(diào)用擦囊。除非該activity是被用戶主動銷毀的西采,通常onSaveInstanceState()只適合用于保存一些臨時性的狀態(tài)举塔,而onPause()適合用于數(shù)據(jù)的持久化保存罩锐。
- onSaveInstanceState()被執(zhí)行的場景有哪些诺舔?
- 系統(tǒng)不知道你按下HOME后要運行多少其他的程序鳖昌,自然也不知道activityA是否會被銷毀,因此系統(tǒng)都會調(diào)用onSaveInstanceState()低飒,讓用戶有機會保存某些非永久性的數(shù)據(jù)许昨。以下幾種情況的分析都遵循該原則當用戶按下HOME鍵時
- 長按HOME鍵,選擇運行其他的程序時
- 鎖屏時
- 從activity A中啟動一個新的activity時
- 屏幕方向切換時
1.0.0.3 如何避免配置改變時Activity重建褥赊?優(yōu)先級低的Activity在內(nèi)存不足被回收后怎樣做可以恢復到銷毀前狀態(tài)糕档?
- 如何避免配置改變時Activity重建
- 為了避免由于配置改變導致Activity重建,可在AndroidManifest.xml中對應的Activity中設置android:configChanges="orientation|screenSize"拌喉。此時再次旋轉(zhuǎn)屏幕時速那,該Activity不會被系統(tǒng)殺死和重建,只會調(diào)用onConfigurationChanged尿背。因此端仰,當配置程序需要響應配置改變,指定configChanges屬性田藐,重寫onConfigurationChanged方法即可荔烧。
- 使用場景,比如視頻播放器橫豎屏切換播放視頻汽久,就需要設置這種屬性鹤竭。具體可以看我封裝的視頻播放器庫,地址:https://github.com/yangchong211/YCVideoPlayer
- 優(yōu)先級低的Activity在內(nèi)存不足被回收后怎樣做可以恢復到銷毀前狀態(tài)
- 優(yōu)先級低的Activity在內(nèi)存不足被回收后重新打開會引發(fā)Activity重建景醇。Activity被重新創(chuàng)建時會調(diào)用onRestoreInstanceState(該方法在onStart之后)臀稚,并將onSavaInstanceState保存的Bundle對象作為參數(shù)傳到onRestoreInstanceState與onCreate方法。因此可通過onRestoreInstanceState(Bundle savedInstanceState)和onCreate((Bundle savedInstanceState)來判斷Activity是否被重建三痰,并取出數(shù)據(jù)進行恢復烁涌。但需要注意的是苍碟,在onCreate取出數(shù)據(jù)時一定要先判斷savedInstanceState是否為空。
- 如何判斷activity的優(yōu)先級撮执?技術(shù)博客大總結(jié)
- 除了在棧頂?shù)腶ctivity,其他的activity都有可能在內(nèi)存不足的時候被系統(tǒng)回收微峰,一個activity越處于棧底,被回收的可能性越大.如果有多個后臺進程抒钱,在選擇殺死的目標時蜓肆,采用最近最少使用算法(LRU)。
1.0.0.4 app切換到后臺谋币,當前activity會走onDestory方法嗎仗扬?一般在onstop方法里做什么?什么情況會導致app會被殺死蕾额,這時候會走onDestory嗎早芭?
- app切換到后臺,當前activity會走onDestory方法嗎诅蝶?
- 不會走onDestory方法退个,會先后走onPause和onStop方法。
- 一般在onstop方法里做什么调炬?
- 比如语盈。寫輪播圖的時候,會在onstop方法里寫上暫停輪播圖無限輪播缰泡,在onStart方法中會開啟自動無限輪播刀荒。
- 再比如,寫視頻播放器的時候棘钞,當app切換到后臺缠借,則需要停止視頻播放,也是可以在onstop中處理的宜猜。關(guān)于視頻播放器烈炭,可以看我這個開源項目:視頻播放器
- 什么情況會導致app會被殺死,這時候會走onDestory嗎宝恶?
- 系統(tǒng)資源不足符隙,會導致app意外被殺死。應用只有在進程存活的情況下才會按照正常的生命周期進行執(zhí)行垫毙,如果進程突然被kill掉霹疫,相當于System.exit(0); 進程被殺死,根本不會走(activity综芥,fragment)生命周期丽蝎。只有在進程不被kill掉,正常情況下才會執(zhí)行ondestory()方法。
- activity被回收如何恢復
- 當系統(tǒng)內(nèi)存不足時, activity會被回收屠阻,我們其實可以覆寫onSaveInstanceState()方法红省。onSaveInstanceState()方法接受一個Bundle類型的參數(shù), 開發(fā)者可以將狀態(tài)數(shù)據(jù)存儲到這個Bundle對象中,這樣即使activity被系統(tǒng)摧毀,當用戶重新啟動這個activity而調(diào)用它的onCreate()方法時,上述的Bundle對象會作為實參傳遞給onCreate()方法,開發(fā)者可以從Bundle對象中取出保存的數(shù)據(jù), 然后利用這些數(shù)據(jù)將activity恢復到被摧毀之前的狀態(tài)。
1.0.0.5 Activity的啟動過程是有幾種方式国觉?從桌面launcher上點擊應用圖標會干啥吧恃,調(diào)用startActivty()又會做什么?
- Activity的啟動過程是怎樣的麻诀,有幾種方式痕寓?
- 注意是啟動過程,不是生命周期蝇闭。技術(shù)博客大總結(jié)
- app啟動的過程有兩種情況呻率,第一種是從桌面launcher上點擊相應的應用圖標,第二種是在activity中通過調(diào)用startActivity來啟動一個新的activity呻引。
- 從桌面launcher上點擊應用圖標會干啥礼仗,調(diào)用startActivty()又會做什么?
- 創(chuàng)建一個新的項目逻悠,默認的根activity都是MainActivity元践,而所有的activity都是保存在堆棧中的,啟動一個新的activity就會放在上一個activity上面蹂风,而我們從桌面點擊應用圖標的時候卢厂,由于launcher本身也是一個應用乾蓬,當我們點擊圖標的時候惠啄,系統(tǒng)就會調(diào)用startActivitySately(),一般情況下,我們所啟動的activity的相關(guān)信息都會保存在intent中任内,比如action撵渡,category等等。
- 我們在安裝這個應用的時候死嗦,系統(tǒng)也會啟動一個PackaManagerService的管理服務趋距,這個管理服務會對AndroidManifest.xml文件進行解析,從而得到應用程序中的相關(guān)信息越除,比如service节腐,activity,Broadcast等等摘盆,然后獲得相關(guān)組件的信息翼雀。
- 當我們點擊應用圖標的時候,就會調(diào)用startActivitySately()方法孩擂,而這個方法內(nèi)部則是調(diào)用startActivty(),而startActivity()方法最終還是會調(diào)用startActivityForResult()這個方法狼渊。而在startActivityForResult()這個方法。因為startActivityForResult()方法是有返回結(jié)果的类垦,所以系統(tǒng)就直接給一個-1狈邑,就表示不需要結(jié)果返回了城须。
- 而startActivityForResult()這個方法實際是通過Instrumentation類中的execStartActivity()方法來啟動activity,Instrumentation這個類主要作用就是監(jiān)控程序和系統(tǒng)之間的交互米苹。而在這個execStartActivity()方法中會獲取ActivityManagerService的代理對象糕伐,通過這個代理對象進行啟動activity。啟動會就會調(diào)用一個checkStartActivityResult()方法驱入,如果說沒有在配置清單中配置有這個組件赤炒,就會在這個方法中拋出異常了。
- 當然最后是調(diào)用的是Application.scheduleLaunchActivity()進行啟動activity亏较,而這個方法中通過獲取得到一個ActivityClientRecord對象莺褒,而這個ActivityClientRecord通過handler來進行消息的發(fā)送,系統(tǒng)內(nèi)部會將每一個activity組件使用ActivityClientRecord對象來進行描述雪情,而ActivityClientRecord對象中保存有一個LoaderApk對象遵岩,通過這個對象調(diào)用handleLaunchActivity來啟動activity組件,而頁面的生命周期方法也就是在這個方法中進行調(diào)用巡通。
1.0.0.6 說下Activity的四種啟動模式尘执?singleTop和singleTask的區(qū)別以及應用場景?任務棧的作用是什么宴凉?
- Activity的四種啟動模式
- standard標準模式:每次啟動一個Activity就會創(chuàng)建一個新的實例
- singleTop棧頂復用模式:如果新Activity已經(jīng)位于任務棧的棧頂誊锭,就不會重新創(chuàng)建,并回調(diào) onNewIntent(intent) 方法
- singleTask棧內(nèi)復用模式:只要該Activity在一個任務棧中存在弥锄,都不會重新創(chuàng)建丧靡,并回調(diào) onNewIntent(intent) 方法。如果不存在籽暇,系統(tǒng)會先尋找是否存在需要的棧温治,如果不存在該棧,就創(chuàng)建一個任務棧戒悠,并把該Activity放進去熬荆;如果存在,就會創(chuàng)建到已經(jīng)存在的棧中
- singleInstance單實例模式:具有此模式的Activity只能單獨位于一個任務棧中绸狐,且此任務棧中只有唯一一個實例
- singleTop和singleTask的區(qū)別以及應用場景
- singleTop:同個Activity實例在棧中可以有多個卤恳,即可能重復創(chuàng)建;該模式的Activity會默認進入啟動它所屬的任務棧寒矿,即不會引起任務棧的變更突琳;為防止快速點擊時多次startActivity,可以將目標Activity設置為singleTop
- singleTask:同個Activity實例在棧中只有一個劫窒,即不存在重復創(chuàng)建本今;可通過android:taskAffinity設定該Activity需要的任務棧,即可能會引起任務棧的變更;常用于主頁和登陸頁
- singleTop或singleTask的Activity在以下情況會回調(diào)onNewIntent()
- singleTop:如果新Activity已經(jīng)位于任務棧的棧頂冠息,就不會重新創(chuàng)建挪凑,并回調(diào) onNewIntent(intent) 方法
- singleTask:只要該Activity在一個任務棧中存在,都不會重新創(chuàng)建逛艰,并回調(diào) onNewIntent(intent) 方法
- 任務棧的作用是什么躏碳?技術(shù)博客大總結(jié)
- 它是存放 Activity 的引用的,Activity不同的啟動模式散怖,對應不同的任務棧的存放菇绵;可通過 getTaskId()來獲取任務棧的 ID,如果前面的任務棧已經(jīng)清空镇眷,新開的任務棧ID+1咬最,是自動增長的;首先來看下Task的定義欠动,Google是這樣定義Task的:Task實際上是一個Activity棧永乌,通常用戶感受的一個Application就是一個Task。從這個定義來看具伍,Task跟Service或者其他Components是沒有任何聯(lián)系的翅雏,它只是針對Activity而言的。
1.0.0.7 兩個Activity之間怎么傳遞數(shù)據(jù)人芽?intent和bundle有什么區(qū)別望几?為什么有了intent還要設計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還要設計bundle害碾?
- 兩者比較
- Bundle只是一個信息的載體矢劲,內(nèi)部其實就是維護了一個Map<String,Object>赦拘。
- Intent負責Activity之間的交互,內(nèi)部是持有一個Bundle的芬沉。
- bundle使用場景
- Fragment之間傳遞數(shù)據(jù)躺同;比如,某個Fragment中點擊按鈕彈出一個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啟動模式的標記位?flag是干什么用的黄刚,什么時候用到捎谨?
- 常見的標記為:
- FLAG_ACTIVITY_SINGLE_TOP:對應singleTop啟動模式
- FLAG_ACTIVITY_NEW_TASK :對應singleTask模式
1.0.1.0 同一程序不同的Activity是否可以放在不同的Task任務棧中?
- 同一程序不同的Activity是否可以放在不同的Task任務棧中?
- 可以的涛救。比如:啟動模式里有個Singleinstance畏邢,可以運行在另外的單獨的任務棧里面。用這個模式啟動的activity检吆,在內(nèi)存中只有一份舒萎,這樣就不會重復的開啟。
- 也可以在激活一個新的activity時候,給intent設置flag蹭沛,Intent的flag添加FLAG_ACTIVITY_NEW_TASK臂寝,這個被激活的activity就會在新的task棧里面
1.0.1.1 介紹一下Service,啟動Service有幾種方式摊灭,生命周期是怎樣的咆贬?說一下onStartCommand()的作用?service如何殺不死帚呼?
- Service分為兩種
- 本地服務素征,屬于同一個應用程序,通過startService來啟動或者通過bindService來綁定并且獲取代理對象萝挤。如果只是想開個服務在后臺運行的話御毅,直接startService即可,如果需要相互之間進行傳值或者操作的話怜珍,就應該通過bindService端蛆。
- 遠程服務(不同應用程序之間),通過bindService來綁定并且獲取代理對象酥泛。
- 對應的生命周期如下:
- context.startService() ->onCreate()- >onStartCommand()->Service running--調(diào)用context.stopService() ->onDestroy()
- context.bindService()->onCreate()->onBind()->Service running--調(diào)用>onUnbind() -> onDestroy()
- 注意
- Service默認是運行在main線程的今豆,因此Service中如果需要執(zhí)行耗時操作(大文件的操作,數(shù)據(jù)庫的拷貝柔袁,網(wǎng)絡請求呆躲,文件下載等)的話應該在子線程中完成。
- Service生命周期解釋技術(shù)博客大總結(jié)
- onCreate():服務第一次被創(chuàng)建時調(diào)用
- onStartComand():服務啟動時調(diào)用
- onBind():服務被綁定時調(diào)用
- onUnBind():服務被解綁時調(diào)用
- onDestroy():服務停止時調(diào)用
- 說一下onStartCommand()的作用捶索?
- service如何殺不死插掂?
- 1.onStartCommand方法,返回START_STICKY(粘性)當service因內(nèi)存不足被kill腥例,當內(nèi)存又有的時候辅甥,service又被重新創(chuàng)建
- 2.設置優(yōu)先級,在服務里的ondestory里發(fā)送廣播 在廣播里再次開啟這個服務,雙進程守護
1.0.1.2 一個Activty先start一個Service后燎竖,再bind時會回調(diào)什么方法璃弄?此時如何做才能回調(diào)Service的destory()方法?
- 關(guān)于service中onDestroy()什么時候會被執(zhí)行构回?
- 當調(diào)用了startService()方法后夏块,又去調(diào)用stopService()方法疏咐,這時服務中的onDestroy()方法就會執(zhí)行,表示服務已經(jīng)銷毀了脐供。
- 類似地凳鬓,當調(diào)用了 bindService()方法后,又去調(diào)用unbindService()方法患民,onDestroy()方法也會執(zhí)行缩举,這兩種情況都很好理解。
-
一個Activty先start一個Service后匹颤,再bind時會回調(diào)什么方法仅孩?
- 先start后bind操作service,此時如何做才能回調(diào)Service的destory()方法印蓖?
- 完全有可能對一個服務既調(diào)用了startService()方法辽慕,又調(diào)用了bindService()方法的,這種情況下該如何才能讓服務銷毀掉呢赦肃?根據(jù)Android系統(tǒng)的機制溅蛉,一個服務只要被啟動或者被綁定了之后,就會一直處于運行狀態(tài)他宛,必須要讓以上兩種條件同時不滿足船侧,服務才能被銷毀。
- 這種情況下要同時調(diào)用stopService()和unbindService()方法厅各,onDestroy()方法才會執(zhí)行這樣就把服務的生命周期完整地走了一遍镜撩。技術(shù)博客大總結(jié)
1.0.1.3 bindService是一個異步的過程嗎?綁定service大概需要經(jīng)歷那些過程队塘?
1.0.1.4 是否能在Service進行耗時操作袁梗?如果非要可以怎么做,如何避免service線程卡頓憔古?service里面可以彈土司嗎遮怜?
- 是否能在Service進行耗時操作?
- 默認情況,如果沒有顯示的指定service所運行的進程,Service和Activity是運行在當前app所在進程的mainThread(UI主線程)里面鸿市。
- service里面不能執(zhí)行耗時的操作(網(wǎng)絡請求,拷貝數(shù)據(jù)庫,大文件)锯梁,在Service里執(zhí)行耗時操作,有可能出現(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)部類,并添加相應的邏輯方法赔硫。重寫Service的onBind方法炒俱,返回我們剛剛定義的那個內(nèi)部類實例。Activity中創(chuàng)建一個ServiceConnection的匿名內(nèi)部類爪膊,并且重寫里面的onServiceConnected方法和onServiceDisconnected方法权悟,這兩個方法分別會在活動與服務成功綁定以及解除綁定的時候調(diào)用,在onServiceConnected方法中推盛,我們可以得到一個剛才那個service的binder對象峦阁,通過對這個binder對象進行向下轉(zhuǎn)型,得到我們那個自定義的Binder實例耘成,有了這個實例榔昔,做可以調(diào)用這個實例里面的具體方法進行需要的操作了
- 方法二
- 通過BroadCast(廣播)的形式,當我們的進度發(fā)生變化的時候我們發(fā)送一條廣播瘪菌,然后在Activity的注冊廣播接收器撒会,接收到廣播之后更新視圖
1.0.2.0 是否了解ActivityManagerService,它發(fā)揮什么作用师妙,說一下AMS啟動流程茧彤?
1.0.2.1 Android中哪些事件需要用到廣播珠洗?廣播的生命周期是怎樣的?
- Android中哪些事件需要用到廣播若专?
- Android中:系統(tǒng)在運行過程中许蓖,會產(chǎn)生會多事件,那么某些事件產(chǎn)生時调衰,比如:電量改變膊爪、收發(fā)短信、撥打電話嚎莉、屏幕解鎖米酬、開機,系統(tǒng)會發(fā)送廣播趋箩,只要應用程序接收到這條廣播赃额,就知道系統(tǒng)發(fā)生了相應的事件加派,從而執(zhí)行相應的代碼。使用廣播接收者跳芳,就可以收聽廣播
- 廣播的生命周期是怎樣的芍锦?
- a.廣播接收者的生命周期非常短暫的,在接收到廣播的時候創(chuàng)建飞盆,onReceive()方法結(jié)束之后銷毀娄琉;
- b.廣播接收者中不要做一些耗時的工作,否則會彈出 Application No Response錯誤對話框吓歇;
- c.最好也不要在廣播接收者中創(chuàng)建子線程做耗時的工作车胡,因為廣播接收者被銷毀后進程就成為了空進程,很容易被系統(tǒng)殺掉照瘾;
- d.耗時的較長的工作最好放在服務中完成匈棘;
1.0.2.3 廣播有幾種形式?他們分別有什么特點析命,如何使用廣播主卫?廣播是怎么實現(xiàn)不同進程之間通信的?
- 廣播有幾種形式
- 普通廣播:一種完全異步執(zhí)行的廣播鹃愤,在廣播發(fā)出之后簇搅,所有的廣播接收器幾乎都會在同一時刻接收到這條廣播消息,因此它們接收的先后是隨機的软吐。
- 有序廣播:一種同步執(zhí)行的廣播瘩将,在廣播發(fā)出之后,同一時刻只會有一個廣播接收器能夠收到這條廣播消息凹耙,當這個廣播接收器中的邏輯執(zhí)行完畢后姿现,廣播才會繼續(xù)傳遞,所以此時的廣播接收器是有先后順序的肖抱,且優(yōu)先級(priority)高的廣播接收器會先收到廣播消息备典。有序廣播可以被接收器截斷使得后面的接收器無法收到它叹誉。
- 本地廣播:發(fā)出的廣播只能夠在應用程序的內(nèi)部進行傳遞膏秫,并且廣播接收器也只能接收本應用程序發(fā)出的廣播。
- 粘性廣播:這種廣播會一直滯留方妖,當有匹配該廣播的接收器被注冊后荤崇,該接收器就會收到此條廣播拌屏。
- 廣播的兩種注冊形式技術(shù)博客大總結(jié)
- 廣播的注冊有兩種方法:一種在活動里通過代碼動態(tài)注冊,另一種在配置文件里靜態(tài)注冊术荤。兩種方式的相同點是都完成了對接收器以及它能接收的廣播值這兩個值的定義倚喂;不同點是動態(tài)注冊的接收器必須要在程序啟動之后才能接收到廣播,而靜態(tài)注冊的接收器即便程序未啟動也能接收到廣播喜每,比如想接收到手機開機完成后系統(tǒng)發(fā)出的廣播就只能用靜態(tài)注冊了务唐。
- 動態(tài)注冊
- 需要使用廣播接收者時雳攘,執(zhí)行注冊的代碼带兜,不需要時枫笛,執(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是匹配的浑彰,如果找到了恭理,就把該廣播接收者的進程啟動起來。
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中需要的時候調(diào)用接口的方法勇劣,值可以作為參數(shù)放在這個方法中靖避,然后讓Activity實現(xiàn)這個接口,必然會重寫這個方法比默,這樣值就傳到了Activity中
- Fragment與Fragment之間是如何傳值的幻捏?
- 第一種:
- 通過findFragmentByTag得到另一個的Fragment的對象,這樣就可以調(diào)用另一個的方法了命咐。
- 第二種:
- 第三種:
- 通過setArguments,getArguments的方式醋奠。
1.0.2.9 Activity創(chuàng)建Fragment的方式是什么榛臼?FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別伊佃?
- Activity創(chuàng)建Fragment的方式是什么?
- 靜態(tài)創(chuàng)建具體步驟
- 首先我們同樣需要注冊一個xml文件沛善,然后創(chuàng)建與之對應的java文件航揉,通過onCreatView()的返回方法進行關(guān)聯(lián),最后我們需要在Activity中進行配置相關(guān)參數(shù)即在Activity的xml文件中放上fragment的位置金刁。
- 動態(tài)創(chuàng)建具體步驟
- (1)創(chuàng)建待添加的碎片實例
- (2)獲取FragmentManager帅涂,在活動中可以直接通過調(diào)用 getSupportFragmentManager()方法得到。
- (3)開啟一個事務尤蛮,通過調(diào)用beginTransaction()方法開啟媳友。
- (4)向容器內(nèi)添加或替換碎片,一般使用repalce()方法實現(xiàn)产捞,需要傳入容器的id和待添加的碎片實例醇锚。
- (5)提交事務,調(diào)用commit()方法來完成坯临。
- FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別焊唬?
- FragmnetPageAdapter在每次切換頁面時,只是將Fragment進行分離尿扯,適合頁面較少的Fragment使用以保存一些內(nèi)存求晶,對系統(tǒng)內(nèi)存不會多大影響
- FragmentPageStateAdapter在每次切換頁面的時候,是將Fragment進行回收衷笋,適合頁面較多的Fragment使用芳杏,這樣就不會消耗更多的內(nèi)存
1.0.3.0 fragment 特點?說一下Fragment的生命周期辟宗?如何解決getActivity為null的異常問題爵赵?
1.0.3.1 在fragment中為什么有時getActivity()會為null谨湘?Fragment試圖為什么有的時候會重疊,怎么產(chǎn)生的,又如何解決紧阔?
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來傳遞,因為當橫豎屏會調(diào)用fragment的空參構(gòu)造函數(shù)别伏,數(shù)據(jù)丟失蹄衷。
- FragmentManager , add 和 replace 有什么區(qū)別?
- 使用FragmentTransaction的時候,它提供了這樣兩個方法厘肮,一個add愧口,一個replace,add和replace影響的只是界面,而控制回退的类茂,是事務耍属。
- add 是把一個fragment添加到一個容器container里。replace是先remove掉相同id的所有fragment巩检,然后在add當前的這個fragment厚骗。技術(shù)博客大總結(jié)
- 在大部分情況下,這兩個的表現(xiàn)基本相同碴巾。因為溯捆,一般,咱們會使用一個FrameLayout來當容器,而每個Fragment被add 或者 replace 到這個FrameLayout的時候提揍,都是顯示在最上層的啤月。所以你看到的界面都是一樣的。但是劳跃,使用add的情況下谎仲,這個FrameLayout其實有2層,多層肯定要比一層的來得浪費刨仑,所以還是推薦使用replace郑诺。當然有時候還是需要使用add的。比如要實現(xiàn)輪播圖的效果杉武,每個輪播圖都是一個獨立的Fragment辙诞,而他的容器FrameLayout需要add多個Fragment,這樣他就可以根據(jù)提供的邏輯進行輪播了轻抱。而至于返回鍵的時候飞涂,這個跟事務有關(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對象官卡,該對象唯一,不會重復創(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粘舟、設置為不可見INVISIBLE熔脂、建立DecorView和Activity的聯(lián)系。
- 獲取Activity的WindowManager
- 調(diào)用WindowManager.addView(decorView, ...)將DecorView添加到WM中柑肴,完成顯示的工作霞揉。
- 何時將DecorView設置為VISIBLE?并且顯示出來?技術(shù)博客大總結(jié)
- 也是在handleResumeActivity中
- 現(xiàn)將DecorView設置為不可見
- wm.addView(): 將DecorView添加到Window總
- 然后執(zhí)行makeVisible讓DecorView可見
1.0.4.0 Intent是什么晰骑?Intent可以傳遞哪些數(shù)據(jù)适秩?傳遞對象的時候為什么要實例化?
- Intent是一種運行時綁定(run-time binding)機制,它能在程序運行過程中連接兩個不同的組件秽荞。
- 舉例:比如骤公,有一個Activity希望打開網(wǎng)頁瀏覽器查看某一網(wǎng)頁的內(nèi)容,那么這個Activity只需要發(fā)出 WEB_SEARCH_ACTION給Android
- Android就會根據(jù)Intent的請求內(nèi)容扬跋,查詢各組件注冊時聲明的 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機制,譯成串行化朴上、序列化……垒棋,其作用是能將數(shù)據(jù)對象存入字節(jié)流當中,在需要時重新生成對象余指。主要應用是利用外部存儲設 備保存對象狀 態(tài)捕犬,以及通過網(wǎng)絡傳輸對象等跷坝。
- 第二種:在Android系統(tǒng)中酵镜,定位為針對內(nèi)存受限的設備,因此對性能要求更高柴钻,另外系統(tǒng)中采用了新的IPC(進程間通信)機制淮韭,必然要求使用性能更出色的對象傳輸方式。
1.0.1.2 Activity如與Service通信贴届?Service的生命周期與啟動方法由什么區(qū)別靠粪?
可以通過bindService的方式,先在Activity里實現(xiàn)一個ServiceConnection接口毫蚓,并將該接口傳遞給bindService()方法占键,在ServiceConnection接口的onServiceConnected()方法
里執(zhí)行相關(guān)操作。
Service的生命周期與啟動方法由什么區(qū)別元潘?
startService():開啟Service畔乙,調(diào)用者退出后Service仍然存在。
bindService():開啟Service翩概,調(diào)用者退出后Service也隨即退出牲距。
Service生命周期:
只是用startService()啟動服務:onCreate() -> onStartCommand() -> onDestory
只是用bindService()綁定服務:onCreate() -> onBind() -> onUnBind() -> onDestory
同時使用startService()啟動服務與bindService()綁定服務:onCreate() -> onStartCommnad() -> onBind() -> onUnBind() -> onDestory
1.1.0.4 廣播有哪些注冊方式?有什么區(qū)別钥庇?廣播發(fā)送和接收原理是什么[binder如何運作的]牍鞠?
- 廣播有哪些注冊方式?
- 靜態(tài)注冊:常駐系統(tǒng)评姨,不受組件生命周期影響难述,即便應用退出,廣播還是可以被接收,耗電胁后、占內(nèi)存硫眯。
- 動態(tài)注冊:非常駐,跟隨組件的生命變化择同,組件結(jié)束两入,廣播結(jié)束。在組件結(jié)束前敲才,需要先移除廣播裹纳,否則容易造成內(nèi)存泄漏。
- 廣播發(fā)送和接收原理是什么[binder如何運作的]紧武?
- 繼承BroadcastReceiver剃氧,重寫onReceive()方法。
- 通過Binder機制向ActivityManagerService注冊廣播阻星。
- 通過Binder機制向ActivityMangerService發(fā)送廣播朋鞍。
- ActivityManagerService查找符合相應條件的廣播(IntentFilter/Permission)的BroadcastReceiver,將廣播發(fā)送到BroadcastReceiver所在的消息隊列中妥箕。
- BroadcastReceiver所在消息隊列拿到此廣播后滥酥,回調(diào)它的onReceive()方法。
1.0.4.1 mipmap系列中xxxhdpi畦幢、xxhdpi坎吻、xhdpi、hdpi宇葱、mdpi和ldpi存在怎樣的關(guān)系瘦真?
- 表示不同密度的圖片資源,像素從高到低依次排序為xxxhdpi>xxhdpi>xhdpi>hdpi>mdpi>ldpi黍瞧,根據(jù)手機的dpi不同加載不同密度的圖片
1.0.4.2 res目錄和assets目錄的區(qū)別诸尽?
- assets:不會在 R文件中生成相應標記,存放到這里的資源在打包時會打包到程序安裝包中印颤。(通過 AssetManager 類訪問這些文件)
- res:會在 R 文件中生成 id標記您机,資源在打包時如果使用到則打包到安裝包中,未用到不會打入安裝包中膀哲。
- res/anim:存放動畫資源
- res/raw:和 asset下文件一樣往产,打包時直接打入程序安裝包中(會映射到 R文件中)
1.0.4.3 Context是什么?Context有哪些類型某宪,分別作用是什么仿村?Context下有哪些子類?哪些場景只能用activity上下文兴喂?
- Context是什么蔼囊?
- Context是一個抽象基類焚志。在翻譯為上下文,也可以理解為環(huán)境畏鼓,是提供一些程序的運行環(huán)境基礎信息酱酬。
- Context有哪些類型,分別作用是什么云矫?
- Context下有兩個子類膳沽,ContextWrapper是上下文功能的封裝類,而ContextImpl則是上下文功能的實現(xiàn)類让禀。
- ContextWrapper又有三個直接的子類挑社,ContextThemeWrapper、Service和Application巡揍。其中痛阻,ContextThemeWrapper是一個帶主題的封裝類,而它有一個直接子類就是Activity腮敌,所以Activity和Service以及Application的Context是不一樣的阱当,只有Activity需要主題,Service不需要主題糜工。
- Context下有哪些子類弊添,主要是干什么的?
- Context一共有三種類型啤斗,分別是Application表箭、Activity和Service。
- 這三個類雖然分別各種承擔著不同的作用钮莲,但它們都屬于Context的一種,而它們具體Context的功能則是由ContextImpl類去實現(xiàn)的彼水,因此在絕大多數(shù)場景下崔拥,Activity、Service和Application這三種類型的Context都是可以通用的凤覆。
- 不過有幾種場景比較特殊链瓦,比如啟動Activity,還有彈出Dialog盯桦。出于安全原因的考慮慈俯,Android是不允許Activity或Dialog憑空出現(xiàn)的,一個Activity的啟動必須要建立在另一個Activity的基礎之上拥峦,也就是以此形成的返回棧贴膘。而Dialog則必須在一個Activity上面彈出(除非是系統(tǒng)級別吐司),因此在這種場景下略号,我們只能使用Activity類型的Context刑峡,否則將會出錯洋闽。
1.0.4.4 ActivityThread的main()的流程大概是怎么樣的?
- ActivityThread的main()的流程大概是怎么樣的突梦?
1.0.5.0 序列化的方式有哪些诫舅?效率對比有何優(yōu)勢?如何做性能上分析的宫患?
- 序列化的方式有哪些
- Parcelable
- Parcelable是Android特有的一個實現(xiàn)序列化的接口刊懈,在Parcel內(nèi)部包裝了可序列化的數(shù)據(jù),可以在Binder中自由傳輸娃闲。序列化的功能由writeToParcel方法來完成俏讹,最終通過Parcel的一系列write方法完成。反序列化功能由CREAOR來完成畜吊,其內(nèi)部標明了如何創(chuàng)建序列化對象和數(shù)組泽疆,并通過Parcel的一系列read方法來完成反序列化的過程。
- Serializable
- Serializable是Java提供的一個序列化接口玲献,是一個空接口殉疼,用于標示對象是否可以支持序列化,通過ObjectOutputStrean及ObjectInputStream實現(xiàn)序列化和反序列化的過程捌年。注意可以為需要序列化的對象設置一個serialVersionUID瓢娜,在反序列化的時候系統(tǒng)會檢測文件中的serialVersionUID是否與當前類的值一致,如果不一致則說明類發(fā)生了修改礼预,反序列化失敗眠砾。因此對于可能會修改的類最好指定serialVersionUID的值。
1.0.5.9 界面的刷新為什么需16.6ms托酸?畫面的顯示需要哪些步驟褒颈?界面保持不變時還會16.6ms刷新一次屏幕嗎?
- 界面的刷新為什么需16.6ms励堡?
- 系統(tǒng)每16.6ms會發(fā)出一個VSYNC信號谷丸,發(fā)出信號后,才會開始進行測量应结、布局和繪制刨疼。
- 發(fā)出VSYNC信號時,還會將此時顯示器的buffer緩沖區(qū)的數(shù)據(jù)取出鹅龄,并顯示在屏幕上揩慕。
- 畫面的顯示需要哪些步驟?
- CPU計算數(shù)據(jù)(View樹遍歷并執(zhí)行三大流程:測量扮休、布局和繪制)迎卤,然后將數(shù)據(jù)交給GPU“
- GPU渲染處理,然后將數(shù)據(jù)放到Buffer中肛炮。
- 顯示屏(display)從buffer中取出數(shù)據(jù)止吐,并進行顯示宝踪。
- 界面保持不變時還會16.6ms刷新一次屏幕嗎?技術(shù)博客大總結(jié)
- 對于底層顯示器碍扔,每間隔16.6ms接收到VSYNC信號時瘩燥,就會用buffer中數(shù)據(jù)進行一次顯示。所以一定會刷新不同。
- 界面刷新的本質(zhì)流程
- 通過ViewRootImpl的scheduleTraversals()進行界面的三大流程厉膀。
- 調(diào)用到scheduleTraversals()時不會立即執(zhí)行,而是將該操作保存到待執(zhí)行隊列中二拐。并給底層的刷新信號注冊監(jiān)聽服鹅。
- 當VSYNC信號到來時,會從待執(zhí)行隊列中取出對應的scheduleTraversals()操作百新,并將其加入到主線程的消息隊列中企软。
- 主線程從消息隊列中取出并執(zhí)行三大流程: onMeasure()-onLayout()-onDraw()
1.0.6.0 Android中日志級別有哪幾種?開發(fā)中需要注意什么問題饭望,打印日志源碼分析原理是什么仗哨?
- Android中日志級別有哪幾種?
- 1.Log.v 的輸出顏色為黑色的铅辞,輸出大于或等于VERBOSE日志級別的信息厌漂,也就是可見級別,一般是最低的信息提示
- 2.Log.d的輸出顏色是藍色的斟珊,也就是調(diào)式級別苇倡,一般不會中止程序,一般是程序員為了調(diào)試而打印的log
- 3.Log.i的輸出為綠色囤踩,輸出大于或等于INFO日志級別的信息旨椒,也就是信息界級別,不會中止程序高职,一般是系統(tǒng)中執(zhí)行操作的信息提示
- 4.Log.w的輸出為橙色, 輸出大于或等于WARN日志級別的信息钩乍,也就是警告級別,一般不會中止程序怔锌,但是可能會影響程序執(zhí)行結(jié)果
- 5.Log.e的輸出為紅色,僅輸出ERROR日志級別的信息变过,也就是錯誤級別埃元,一般會中止程序運行,是最嚴重的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方法糊肠,然后在源碼中查看,其實其內(nèi)部調(diào)用的是println_native方法遗锣,也就是通過JNI調(diào)用底層的c++輸出日志货裹。
關(guān)于其他內(nèi)容介紹
01.關(guān)于博客匯總鏈接
02.關(guān)于我的博客