在問題的最右處對問題進(jìn)行等級評定虐唠,層層深入
1.Android線程之間的異步通信有哪些?(C)
handler.sendMessage AsyncTask View.post(Runnable) Activity.runOnUiThread Loaders等
- 1-1handler深入烫饼,looper,messageQueue是怎么合作工作的(B)
在ActivityThread啟動main方法中,會去創(chuàng)建looper對象,并且與主線程進(jìn)行綁定.一個線程只有一個looper,這個looper管理著自己的messageQueue,創(chuàng)建綁定完之后就進(jìn)入了無限循環(huán)從messageQueue中取消息,只要應(yīng)用不退出,就無限循環(huán).接著只要我們在主線程中新建handler對象,就會跟創(chuàng)建該handler的線程的looper綁定(在handler的構(gòu)造函數(shù)中),之后looper負(fù)責(zé)將handler send出來的message加入到queue的尾部,然后再由looper負(fù)責(zé)將message從queue的頭取出(經(jīng)過loop方法中的dispatchMessage進(jìn)行消息分發(fā)),執(zhí)行handleMessage.
1-1-1可以直接在線程中直接new一個handler出來使用么?要注意什么呢恩溅?如果不注意會報什么錯誤呢乓序?(A)
在子線程中創(chuàng)建handler的時候一定要注意創(chuàng)建的時候需要同時去創(chuàng)建looper,否則會由于在子線程中沒有綁定的looper對象而報錯.報錯無能直接在子線程中建立handler的錯誤.
1-1-2android在啟動了之后為什么可以直接在activity中new一個handler進(jìn)行使用呢(A)
因為在ActivityThread中系統(tǒng)已經(jīng)幫主線程創(chuàng)建并且綁定好了looper,這個時候只要new一個handler,在handler的構(gòu)造函數(shù)中就會自動的將handler自身與looper進(jìn)行綁定
- 1-2asynctask是怎么使用的呢寺酪?怎么構(gòu)建舟奠,方法怎么調(diào)用?三個參數(shù)傳入的分別是什么呢房维?(C)
自定義后通過new出來對象,執(zhí)行對象的excute方法實現(xiàn). 常見的方法onPreExecute和onPostExecute分別在doinbackground方法前后執(zhí)行,doinbackground負(fù)責(zé)在子線程中執(zhí)行任務(wù),然后將結(jié)果交由onPostExcute在主線程中處理,同時可以由onProgressUpdate來進(jìn)行實時的將處理狀態(tài)返回給主線程處理.定義時的三個參數(shù),依次為傳入的參數(shù)類型;第二個參數(shù)為后臺處理的進(jìn)度顯式類型,是int還是float還是其他;第三個參數(shù)是doinbackground執(zhí)行之后return給onPostExecute接受的結(jié)果類型.
1-2-1asynctask在使用的過程中哪些方法可以進(jìn)行UI操作呢沼瘫?(B)
直接去AsyncTask中去看有MainThread標(biāo)注的都是可以在主線程中執(zhí)行的
onPostExecute onProgressUpdate onPreExecute onCancelled 其實都可以講的通
1-2-2asynctask的最高同時執(zhí)行線程數(shù),可以改么咙俩?怎么改耿戚?(A)
在3.0以前,支持并行處理,也就是說同時可以執(zhí)行多個任務(wù),當(dāng)時是寫死的線程池,同時可以處理的最大線程數(shù)為5個,線程池大小位128,如果同時添加超過128個AsyncTask任務(wù),那么系統(tǒng)就會崩潰.3.0之后改成了串行處理,同時只能處理一個任務(wù).其實不然,其實3.0之后變得更加靈活,可以自己去定義Executor
Executor exec = new ThreadPoolExecutor(15, 200, 10,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
new DownloadTask().executeOnExecutor(exec);
傳入的三個參數(shù)分別表示,可并行執(zhí)行的最大的線程數(shù),線程池大小,和超過內(nèi)核數(shù)的線程最多可以存活的時間(比如我們有10個線程,內(nèi)核數(shù)為4核,那么多下來的6個線程,最多可以存活如上所述的10秒)
1-2-3asynctask的弊端,(輪個數(shù)評級,A↑)
- 使用cancel方法時無法直接停止子線程,由于調(diào)用了cancel方法會去調(diào)用子線程的interrupt方法,但是這個方法不會直接停止子線程而是只是更改一個標(biāo)志位,具體的停止操作需要用戶在線程中自己做監(jiān)聽.所以oncancel的真正起作用的只不過是不會去調(diào)用onPostExecute
- onPostExecute的時候回調(diào)出來,activity或者fragment對象已經(jīng)被銷毀的話就會出現(xiàn)找不到對象的錯誤.這個時候要么做空判斷,要么自己定義抽象類BaseAsyncTask復(fù)寫onPostExecute,并final它
- 內(nèi)存泄露,在activity的匿名內(nèi)部類AsyncTask,由于AsyncTask的生命周期和activity不同步,當(dāng)activity被銷毀的時候,可能asynctask還在執(zhí)行,那么后者持有的前者對象就會難以釋放,導(dǎo)致內(nèi)存泄露.
- 當(dāng)asynctask在執(zhí)行的時候,activity由于屏幕旋轉(zhuǎn)或其他原因?qū)е轮亟?asyncTask由于持有的是之前的activity的引用,就會導(dǎo)致onPostExecute的代碼不起作用.
- 1-3 主線程阻塞超過幾秒出現(xiàn)ANR阿趁,數(shù)據(jù)庫阻塞呢膜蛔?廣播接受阻塞呢?(B)
主線程5秒未響應(yīng),數(shù)據(jù)庫10秒,廣播10秒未相應(yīng),會出現(xiàn)ANR
- 1-4 View.post(runnable)可以執(zhí)行耗時的操作么?為什么?(B)
不可以執(zhí)行耗時操作,View.post出來的runnable是在UI線程中執(zhí)行的.
2.平時在使用listview的時候都會注意哪些問題脖阵?(C)
圖片的異步加載方面,性能優(yōu)化方面(ViewHolder, convertView,滑動的時候不加載圖片等)
- 2-1在listview中需要加載圖片的話有什么比較好的方法么皂股?(B)
采用異步加載的方式,當(dāng)然可以使用第三方的圖片庫picasso,fresco,也可以自己實現(xiàn).
2-1-1 知道怎么去寫一個imageloader么?(A)
簡易的imageLoader負(fù)責(zé)圖片的異步加載,方法可以不止一個.
將圖片的url設(shè)置為view的tag,將view傳給imageloader,imageloader本身管理著一套lru緩存,將url取出后,先去緩存中查看是否有該圖片,有的話直接回調(diào)顯示,沒有的話進(jìn)行網(wǎng)絡(luò)請求,得到結(jié)果候進(jìn)行網(wǎng)絡(luò)顯示并做本地緩存.如果加載失敗則顯式失敗的畫面的.
2-1-2 有哪些第三方好用的圖片庫命黔,看過源碼么呜呐,可以講一講么,區(qū)別,推薦(A+)
picasso, fresco, glide, Universal-image-loader
如果預(yù)見項目中會有很多圓角或漸進(jìn)式JPEG等需求,可以使用Fresco悍募;
如果是老項目已經(jīng)使用了UIL或者Picasso蘑辑,且依賴較多不容易修改,則可以繼續(xù)使用坠宴;
如果還在糾結(jié)如何避免65K方法數(shù)洋魂,推薦使用Glide代替Fresco因為Glide比后者實在輕巧了太多;
如果是老項目需要換加載庫喜鼓,推薦使用Glide而不是Fresco, 降低遷移工作量副砍;
如果是新項目,不推薦使用已經(jīng)停止維護(hù)的UIL庄岖,也不推薦Picasso豁翎,推薦使用Glide;
- 2-2 如果使用過程中出現(xiàn)了不同的item需要展示不同的布局顿锰,這個時候用什么方法解決谨垃?(B)
使用listView的viewtype去區(qū)別不同的展示
- 2-3 listview怎么去和數(shù)據(jù)庫做綁定呢?(B)
使用cursorAdapter去實現(xiàn)和數(shù)據(jù)庫的綁定
2-3-1 如果想要listview對數(shù)據(jù)庫做實時的更新硼控,會怎么做呢刘陶?(A)
使用cursorLoader綁定listview,用觀察者模式對數(shù)據(jù)庫進(jìn)行監(jiān)聽,一旦有變化,swapcursor,并notifyDataChanged
3. 有使用過自定義控件么,自定義控件從定義到使用牢撼,怎么個流程匙隔,可以粗略的講一下么(B-A)
- 首先我們需要去attr.xml文件中去定義我們控件中需要的一些自定義的屬性.
- 然后創(chuàng)建我們自定義的控件繼承View,主要好復(fù)寫onDraw,onLayout,和onMeasure方法,以及它的構(gòu)造函數(shù).
- onMeasure中根據(jù)傳入的寬高mode,來選擇是否要對控件進(jìn)行計算.如果是wrap_content的則將控件的寬高計算出來setMeasureDimension
- onLayout,經(jīng)過計算過后的measure寬高來獲得控件的坐標(biāo)點,導(dǎo)入onLayout
- 最后在onDraw方法中,利用畫布畫筆對需要的背景或者其他內(nèi)部元素進(jìn)行繪制.
- 在布局文件中,添加自定義view,與自定義命名空間,來使用該自定義控件的屬性.
- 3-1 如果我需要為這個自定義控件創(chuàng)建一些特有的屬性,比如說想要在布局文件中控制它的字體大小熏版,字體顏色纷责,應(yīng)該怎么去做捍掺?(A)
在attr文件中定義自定義屬性,然后在自定義控件的構(gòu)造函數(shù)中通過TypeArray取出,然后對其遍歷index,取出屬性值,做相應(yīng)處理.
- 3-2 除了使用動畫之外,還有什么方法可以實現(xiàn)一個動態(tài)的view再膳?(B)
可以使用surfaceView
3-2-1 surfaceview和一般的view有什么地方不同挺勿?(B)
一般的view都是在主線程中進(jìn)行繪制的,而surfaceView是獨立線程進(jìn)行繪制,因此可以進(jìn)行復(fù)雜的繪制,不會阻塞主線程.
3-2-2 你覺得什么情景中會使用到surfaceview,或者你知道什么地方會用到surfaceview(A)
相機模塊中會使用到,或者是復(fù)雜的動畫顯示,或者是一些游戲界面也會食用到,只要是畫面在不斷的變化的就可以使用surfaceView去實現(xiàn).
3-2-3 在使用surfaceview的時候需要注意一些什么喂柒?什么時候畫不瓶,什么時候不畫?怎么去做(A)
注意啟動和關(guān)閉繪制.由于它的特殊性,我們可以在onResume中啟動繪制,在onPause中停止繪制.
由于自定義的surfaceView需要去實現(xiàn)runnable,在類內(nèi)部實現(xiàn)其run方法,我們可以設(shè)置一個標(biāo)志位,在run方法中進(jìn)行循環(huán)判斷,一旦標(biāo)志位為false就停止繪制,然后可以在view的onPause和onResume中修改標(biāo)志位.
4.有沒有NDK編程經(jīng)驗灾杰,或者說對NDK有了解么蚊丐?(C)
結(jié)合C或C++,進(jìn)行android編程,一般使用比較多的是方法封裝,編譯成so庫文件,供android項目使用.
- 4-1 講一下NDK的一個大體流程,或者說現(xiàn)在給你一個工具類艳吠,如何去調(diào)用C代碼的一些方法麦备?(B)
- 首先需要使用NDK生成相應(yīng)的頭文件,或者是自己寫也行.然后新建.c文件,引用該頭文件,然后注意定義的與java交接的方法名需要與調(diào)用該方法的類的包名相同,要遵循相應(yīng)的規(guī)則.
- 然后在c文件中,實現(xiàn)該方法.之后在gradle中對其進(jìn)行配置.執(zhí)行NDK編譯,在build目錄下得到相應(yīng)文件夾的so文件,將so文件放入jniLib中.
- 在工具類中靜態(tài)加載so庫,然后調(diào)用相應(yīng)方法即可生效.
- 4-1-1 eclipse上的NDK編程和studio上的有什么不同?(A)
eclipse上需要通過Android.mk和application.mk去對該NDK項目進(jìn)行配置,而在studio上直接在gradle中進(jìn)行配置即可.
5. 對當(dāng)今比較流行的框架有了解么昭娩?可以舉出你知道的一些框架么凛篙?(B)
網(wǎng)絡(luò)框架 retrofit,Okhttp,volly等 緩存DIskLruCache等 數(shù)據(jù)庫OrmLite,GreenDao等, 依賴注入Dagger2 butterKnife等 事件總線 eventBus等 RX響應(yīng)式編程 內(nèi)存泄露LeakCanary等等有很多
- 5-1 看過框架的源碼么?講一下框架大概原理题禀,是怎么工作的鞋诗?(A↑)
看具體回答評級
- 5-2 知道RN,聽說過熱修復(fù)么迈嘹?動態(tài)加載,插件化知道多少?(A↑)
reactive-native利用js, html, css重新定義一套規(guī)則, 編寫原生的ios,android移動應(yīng)用.
hotfix,利用動態(tài)加載技術(shù),在用戶手機崩潰時,調(diào)用遠(yuǎn)程服務(wù)端的可執(zhí)行文件,待遠(yuǎn)程將問題解決了之后,現(xiàn)場修復(fù),替換掉有問題的坑,再讓手機執(zhí)行修復(fù)后的本地文件,避免了頻繁的版本更新.比較熱門方案的有AndFix, DexPosed, ClassLoader.熱門的實現(xiàn)有Nuwa,HotFix,DroidFix.
而動態(tài)加載和插件化開發(fā)可以方便大規(guī)模團(tuán)隊協(xié)同開發(fā), 技術(shù)也應(yīng)用于熱補丁修復(fù),將項目開發(fā)模塊化分散.
內(nèi)容比較多,上面也只是個大概,具體看怎么去回答,根據(jù)回答的詳細(xì)情況,了解情況來進(jìn)行評級.
6.對整個手機的布局有了解么全庸?畫一下整個的手機布局框架(B)
觀察是否有phoneWindow和decorView的概念
- 6-1 Activity秀仲,View,Window的關(guān)系是什么壶笼?(B)
我們在activity的attach方法中神僵,會去生成window,就是整個手機的最根的布局覆劈,而這個window的實現(xiàn)類是phoneWindow保礼,在phoneWindow中有一個最頂層的視圖DecorView, 由phoneWIndow將布局文件進(jìn)行解析,然后將相應(yīng)的view加載到DecorVIew中.
- 6-1-1 setcontentView到底是怎么樣把布局文件讓手機屏幕展示出來的(A)
phoneWindow得setContentView方法來將activity的setContentView的布局文件加載到視圖中去,這就是這三者的關(guān)系责语。實際上直接看setContentView的源碼實現(xiàn)就知道它調(diào)用了getWindow().setContentView()再點開發(fā)現(xiàn)是空實現(xiàn)炮障,因為真正的實現(xiàn)就在phoneWindow中。
7. 四個lunchmode(C)
standard,singleTop,singleTask,singleInstance
- 7-1 分別介紹一下使用場景(B)
singleTop 直接吊起activity棧的最頂部activity坤候。 點擊通知推送需要進(jìn)入到一個界面胁赢,那么如果收到多個推送的話,停留在這個界面去點擊這個推送就不用再去重新生成這個界面activity白筹。
singleTask 啟動activity棧中的該activity智末,并把其上的所有activity清空谅摄。 一般用在程序的入口,比如從好幾個應(yīng)用啟動了瀏覽器系馆,只會啟動瀏覽器的主界面一次送漠,瀏覽器主界面之后的activity都會清空掉。
singleInstance 特地為個別activity單獨建立一個activity的棧由蘑,多次重復(fù)利用闽寡。 某個應(yīng)用中用到了google地圖,當(dāng)退出該應(yīng)用再次進(jìn)入google地圖的時候纵穿,還是停留在剛才的畫面下隧。** **
- 7-2 使用singleTask時候會遇到什么問題么?(A↑)比如用startActivityForResult去調(diào)用singleTask的activity會出現(xiàn)什么現(xiàn)象呢谓媒?(A)
啟動singleTask和singleInstance這兩類模式的activity的時候,需要注意不要去用startActivityForResult方法調(diào)用,回立馬收到cancel的回調(diào).
- 7-2-1 那么singleInstance呢淆院?(A)
同
- 7-2-2 如果A真的想要用startActivityForResult去啟動singleTask的B的話怎么辦?(A)
直接在B中再將需要回傳的數(shù)據(jù)通過startActivty(A)的方式去啟動A.
8. 大體講一下觸摸事件分發(fā)吧(B↑)
隧道式的分發(fā)句惯,冒泡式的反饋土辩,一路直接到可以處理觸摸事件的view,然后一路向上按照分發(fā)下來的路徑反向反饋抢野。
最外層的布局調(diào)它的dispatchTouchEvent方法拷淘,在方法中會去看能否攔截,如果可以且需要攔截那就攔截不往下傳遞指孤,否則的話遍歷找到符合條件的子view去調(diào)用它的dispatchTouchEvent启涯,知道最終消費處理這個點擊事件的子view的dispatch方法返回true,然后就不往下傳遞恃轩,并往上走出這個遞歸结洼,這就是viewGroup和view之間的事件分發(fā)機制,結(jié)合view自己的分發(fā)就可以完美解答這個問題叉跛。
- 8-1 intercept返回true松忍,false分別表示什么意思?dispatchTouchEvent呢筷厘?onTouchEvent呢鸣峭?(B)
intercept返回true表示攔截了,onTouch返回true表示被我監(jiān)聽器消耗了酥艳,onTouchEvent表示被我view自己吃了摊溶,然后dispatchTouchEvent表示被我這個view處理消耗了【裂悖總的來說就是返回true代表不往下繼續(xù)傳遞,開始往上傳遞了.
- 8-2 onclick更扁, ontouch,ontouchevent的執(zhí)行的順序是什么?(B)你是怎么知道的(A)
一段源碼告訴你浓镜,在View的dispatchTouchEvent中溃列,onclick是寫在onTouchEvent中的。
所以正確的順序應(yīng)該是onTouch ----> onTouchEvent --------> onClick
9. android的跨進(jìn)程通信知道那些膛薛?(B)
(1) activity的startActivity方式听隐,activity可以直接通過filter去啟動其他應(yīng)用中定義了intent-filter的activity,然后進(jìn)行跨進(jìn)程通信
(2) content provider的跨進(jìn)程共享數(shù)據(jù)
(3) 廣播的被動跨進(jìn)程通信
(4) AIDL的binder機制哄啄。
- 9-1 單單從耦合度分析雅任,廣播機制和binder機制有什么不同呢?(B)
廣播的發(fā)送者和接收者互相都是不知道對方的,而binder則不同,相比前者耦合度更低,可拓展性更強.
9-1-1 廣播的靜態(tài)注冊和動態(tài)注冊分別是怎么實現(xiàn)的呢咨跌?有什么不同呢沪么?(B)
靜態(tài)注冊是在androidManifest文件中進(jìn)行receiver注冊,設(shè)置相應(yīng)的intentfilter的action;動態(tài)注冊直接在代碼中進(jìn)行receiver注冊.不同的地方在于動態(tài)注冊的廣播可以進(jìn)行unRegister,且退出應(yīng)用了之后就不會再接收到廣播,但是靜態(tài)注冊的廣播即使退出了應(yīng)用還是會收到廣播.
10. 移動端的網(wǎng)絡(luò)優(yōu)化,想的到哪些锌半?(B↑)
連接復(fù)用:默認(rèn)情況下禽车,httpurlconnection都是開通了keep-alive的功能的
合并請求:對于界面中出現(xiàn)頻繁請求的情況,可以將請求進(jìn)行合并刊殉,一次性請求殉摔。
請求壓縮: post請求,請求的body或者是header都可以進(jìn)行g(shù)zip壓縮; 對于返回數(shù)據(jù)的格式相差不是很大的记焊,也可以對key部分進(jìn)行壓縮逸月。
根據(jù)用戶的網(wǎng)絡(luò)質(zhì)量,判斷下載什么質(zhì)量的圖片遍膜。本地還可以做靜態(tài)緩存碗硬。
直接訪問IP,而非域名: 使用動態(tài)的IP列表瓢颅,直接訪問IP肛响,一旦IP不能訪問了,再用域名進(jìn)行訪問惜索。
增量更新:對新增的數(shù)據(jù)進(jìn)行更新,bsdiff和bspatch
預(yù)連接和預(yù)取數(shù)據(jù):
對請求分優(yōu)先級
11. service知道多少剃浇,一個service從定義到使用大體講一下巾兆?(B)
Service是由framework層的ActivityServiceManager管理的生命周期長、運行于后臺的服務(wù)性組件虎囚。Service本身是運行在當(dāng)前應(yīng)用進(jìn)程的主線程中角塑,但是可以在Service中開辟子線程以實現(xiàn)音樂播放、數(shù)據(jù)庫交互淘讥、文件操作等耗時操作(因為絕大多數(shù)情況下Service沒有前臺界面)圃伶。需要在manifest文件中聲明
service的啟動有startService和bindService兩種方式,前者當(dāng)應(yīng)用退出時,依然可以運行,除非調(diào)用了stopself或者是系統(tǒng)調(diào)用了stopService,而后者則是通過unbindService解綁.
oncreate方法只會執(zhí)行一次,但是每次調(diào)用都會執(zhí)行onStartCommand(startService)/onBindSerivce(bindService0,當(dāng)調(diào)用了stopSelf或者是stopservice之后如果又綁定就執(zhí)行onUnBind,否則就直接執(zhí)行onDestory方法.
onstartCommand根據(jù)具體的返回值來判斷service被kill了之后如何重啟service.
那么綜上,
- 自定義的service繼承service,我們可以通過具體的需求選擇是復(fù)寫它的onStartCommand方法還是onBind方法去實現(xiàn).
- 去清單文件注冊service
- 通過startService的方式或者是bindService的方式來實現(xiàn).startService直接啟動service,bindService則需要傳入ServiceConnection接口,我們可以在接口方法onServiceConnected中去做邏輯處理,或者自定義處理或者將IBinder取出做處理
- 11-1 service和應(yīng)用是在一個進(jìn)程中么?本身是一個線程么?(B)
本身既不時線程也不是進(jìn)程,service是在主線程中進(jìn)行的.
11-1-1 intentService和service有什么不同呢窒朋?(A)
intentService不用去起新線程就可以執(zhí)行耗時的操作,內(nèi)部是利用handler來處理源源不斷的intent請求,將intent加入隊列,然后依次進(jìn)行處理.所以在intentService中我們只需要去實現(xiàn)onHandleIntent方法就可以了,而service是在主線程中進(jìn)行的,需要去另起線程才可以處理耗時的操作.
intentService需要定義一個構(gòu)造函數(shù),在構(gòu)造函數(shù)中調(diào)用super方法,傳入該服務(wù)的名字,來給intentService命名,因為intentService不需要在manifest文件中注冊.
11-1-2 intenService內(nèi)部源碼看過么搀罢?它是如何做到不用新起線程就可以去執(zhí)行耗時的操作的?(A↑)
實際上就是looper的原理侥猩。我們進(jìn)它的源碼看一看:
新起一個線程榔至,獲得它的looper,創(chuàng)建相應(yīng)的handler
這樣他就通過handler去不斷的循環(huán)新扔進(jìn)來的intent欺劳,然后進(jìn)行處理唧取。所以在intentService中,我們可以直接在onHandleIntent中處理耗時任務(wù)划提。
12. 碰到過哪些異常枫弟,講一講。(B↑)
(1) Can not perform this action after onSaveInstanceState
在Activity保存了狀態(tài)之后鹏往,再對fragmentManger進(jìn)行commit事務(wù)的操作就會造成這個錯誤淡诗,一般最省力的辦法就是把commit改成commitAllowStateLoss
(2) NetWork on main thread
在主線程中進(jìn)行網(wǎng)絡(luò)請求
(3) ClassCastException
類型強轉(zhuǎn)錯誤
(4) IndexOutOfBound
數(shù)組越界
(5) outOfMemory
13. 不同的屏幕分辨率,如何去適配呢掸犬?(C)
最常用的方法是用不同的分辨率文件夾袜漩,保存不同分辨率的圖片到相應(yīng)的文件夾下,對于單色圖標(biāo)來說湾碎,最好的方法是使用矢量圖來解決宙攻,既可以適配不同分辨率,又可以幫apk瘦身介褥。
在布局方面座掘,我們盡可能的去使用relativelayout,強調(diào)的組件和組件之間的位置關(guān)系柔滔,避免了直接將大小寫死溢陪,可以很好的適配不同的分辨率,最新的android.support.constraint.ConstraintLayout更是將其發(fā)揮到極致睛廊⌒握妫或者我們也可以為不同的屏幕做不同的布局,放在相應(yīng)layout文件夾下超全。
- 13-1 知道那些layout咆霜,和drawable文件夾?(C)
各尺寸
- 13-1-1 hdpi和mdpi哪一個大一點(C)
hdpi..
14. 內(nèi)存泄露的原因知道哪些嘶朱?(C)
(1)集合類
只知道添加蛾坯,而沒有做好具體的刪除工作的話,那么如果遇到全局的集合變量疏遏,就會導(dǎo)致這個集合所占用的內(nèi)存只增不減
(2)單例模式
一般見得最多的就是寫的一些util類脉课,為了需要展示或者是做一些需要context的有關(guān)操作救军,就需要傳入context,而為了讓Util可以直接進(jìn)行方法調(diào)用倘零,就會將一些方法寫成static唱遭,然后本類的context對象不得不定義為static,就不得不去靜態(tài)持有外部的對象视事,這樣以來胆萧,當(dāng)外部對象已經(jīng)不可到達(dá)了之后(javaGC),由于被這個util持有俐东,依然無法回收跌穗,就泄露了。
(3)Android特殊的組件需要手動的去關(guān)閉
比如BroadCastReceiver虏辫,ContentReceiver蚌吸,F(xiàn)ileObserver,Callback什么的都需要在onDestory方法或者在activity的生命周期結(jié)束的時候回收砌庄,否則activity會被系統(tǒng)強引用羹唠,無法回收。
(4)handler
只要handler中的message沒有被處理完娄昆,那么這個message就會和他的hander被MessageQueue一直持有佩微,需要在相應(yīng)的位置對handler進(jìn)行removeMessageCallback等操作
(5)線程造成的內(nèi)存泄露
線程的生命周期和activity不一樣,就會導(dǎo)致activity中新起的線程萌焰,持有activity的一個引用哺眯,結(jié)果run方法還沒有結(jié)束的話,activity就不會釋放扒俯,如果此時activity早就已經(jīng)用不到了奶卓,久造成了內(nèi)存泄露。
(6)不良的代碼習(xí)慣
比如bitmap沒有及時的recycle撼玄,各種io流沒有及時的close夺姑,adapter中沒有使用convertView
- 14-1 講一講你所知道的java的GC算法吧 (B↑)
引用計數(shù):一個對象被引用計數(shù)器加一,取消引用計數(shù)器減一掌猛,引用計數(shù)器為0才能被回收盏浙。優(yōu)點:簡單。缺點:不能解決循環(huán)引用的問題荔茬,比如A引用B只盹,B引用A,但是這兩個對象沒有被其他任何對象引用兔院,屬于垃圾對象,卻不能回收站削;每次引用都會附件一個加減法坊萝,影響性能。
標(biāo)記清除法:分為兩個階段:標(biāo)記階段和清除階段。標(biāo)記階段通過根節(jié)點標(biāo)記所有可達(dá)對象十偶,清除階段清除所有不可達(dá)對象菩鲜。缺點:因為清除不可達(dá)對象之后剩余的內(nèi)存不連續(xù),會產(chǎn)生大量內(nèi)存碎片惦积,不利于大對象的分配接校。
復(fù)制算法:將內(nèi)存空間分成相同的兩塊,每次只是用其中的一塊狮崩,垃圾回收時蛛勉,將正在使用的內(nèi)存中的存活對象復(fù)制到另外一塊空間,然后清除正在使用的內(nèi)存空間中的所有對象睦柴,這種回收算法適用于新生代垃圾回收诽凌。優(yōu)點:垃圾回收對象比較多時需要復(fù)制的對象恨少,性能較好坦敌;不會存在內(nèi)存碎片侣诵。缺點:將系統(tǒng)內(nèi)存折半。
標(biāo)記壓縮算法:是一種老年代回收算法狱窘,在標(biāo)記清除的基礎(chǔ)上做了一些優(yōu)化杜顺,首先從根節(jié)點開始標(biāo)記所有不可達(dá)的對象,然后將所有可達(dá)的對象移動到內(nèi)存的一端蘸炸,最后清除所有不可達(dá)的對象躬络。優(yōu)點:不用將內(nèi)存分為兩塊;不會產(chǎn)生內(nèi)存碎片幻馁。
分代算法:新生代使用復(fù)制算法洗鸵,老生帶使用標(biāo)記清除算法或者標(biāo)記壓縮算法。幾乎所有的垃圾回收期都區(qū)分新生代和老生帶仗嗦。
分區(qū)算法:將整個堆空間分成很多個連續(xù)的不同的小空間膘滨,每個小空間獨立使用,獨立回收稀拐。為了更好的控制gc停頓時間火邓,可以根據(jù)目標(biāo)停頓時間合理地回收若干個小區(qū)間,而不是整個堆空間德撬,從而減少gc停頓時間铲咨。
- 14-2 你所知道的哪些東西需要及時的去關(guān)閉或者是釋放的?(B)
比如BroadCastReceiver蜓洪,ContentReceiver纤勒,F(xiàn)ileObserver,Callback什么的都需要在onDestory方法或者在activity的生命周期結(jié)束的時候回收隆檀,否則activity會被系統(tǒng)強引用摇天,無法回收粹湃。
比如bitmap沒有及時的recycle,各種io流沒有及時的close泉坐,adapter中沒有使用convertView
15.scrollView怎么去判斷有沒有滑到了底部为鳄?(A)
首先我們判斷肯定是要放在touch監(jiān)聽當(dāng)中,比如scrollview的onTouchListener或者是他自己的onScrollChange中腕让。
在ontouch中孤钦,當(dāng)檢測到up動作的時候,判斷getScrollY + getHeight = view.getChildAt(0).getMeasureHeight()的時候就是到了底部
或者在onScrollChange方法中纯丸,通過View view = (View)getchildAt(getChildCount() - 1)獲得最下面的一個view(其實就是scrollView包裹的唯一子view)偏形,然后獲得它的高度,view.getBottom()液南,然后當(dāng)這個高度等于scrollY+ getHeight的時候就是滑到了底部
- 15-1 getScrollY()表示什么意思壳猜?
可以理解位控件上方滑出屏幕的距離,如果為負(fù)滑凉,就表示已經(jīng)滑到了控件的頂端
16. assets和raw有什么不同和相同?(C)
兩個文件夾的文件都不會跟著壓制apk被編譯壓縮统扳,都是原封不動的保存。raw文件下不可以再有目錄畅姊,而assets文件下可以再有目錄
raw文件夾下面的文件會映射到R文件中咒钟,調(diào)用的時候直接去使用R.raw.xxxx就可以訪問,getResources().openRawResource(R.raw.rawtext)
而assets文件下的文件訪問的時候需要用到AssetManager若未,AssetManager assets = getAssets(); assets.open(123.txt);
- 16-1 什么時候用assets,什么時候去用raw
有些文件不得不放在raw中朱嘴,因為直接可以通過R文件去訪問,可以直接在xml文件中去訪問他粗合,而assets中由于沒有產(chǎn)生R文件的映射萍嬉,訪問的速度應(yīng)該是沒有Raw文件來的快的。
17. 數(shù)據(jù)持久化的四中方式?(B)
preference隙疚,SQlite壤追,文件I/O,ContentProvider
18. 顯式和隱式的intent調(diào)用分別怎么調(diào)用?(C)
顯式:intent直接定義的時候傳入指定的class供屉,或者是component行冰,或者是setClass/setClassName
隱式:不明確指定具體的class,而是采用setAction的方式伶丐,來啟動注冊了添加了這個action的filter的activity悼做。如果找到一個就打開一個,如果找到多個哗魂,系統(tǒng)會讓你進(jìn)行選擇肛走,,如果一個都沒有找到录别,就跳出來activitynotfoundexception
19. 自定義viewgroup,實現(xiàn)過么?(C)
繼承自ViewGroup羹与,主要的就是實現(xiàn)onMeasure方法和onLayout方法故硅,因為onDraw方法只需要調(diào)用super.onDraw方法即可。
在onMeasure纵搁,根據(jù)獲得父框架給予的寬高大小和寬高模式,來計算子view排布之后的布局的寬高往踢。如果在xml文件中直接定義了dp的具體數(shù)值腾誉,或者是直接是match_parent,則直接調(diào)用setMeasuredDimension((modeWidth == MeasureSpec.EXACTLY)峻呕?sizeWidth: width, (modeHeight == MeasureSpec.EXACTLY) ? sizeHeight: height); 根據(jù)尺寸模式來判斷是要使用自己計算出來的寬高還是父框架給予的寬高
在onLayout中利职,就對子view進(jìn)行排布。定義left = 0瘦癌,和top = 0猪贪,然后根據(jù)分布的規(guī)則,遍歷自view谴麦,計算出他們的left拜隧,top碌补,right,bottom的值桶癣,然后調(diào)用自view的layout方法,去排列它們
- 19-1 具體需要實現(xiàn)哪些方法呢?(B)
onMeasure, onLayout,依據(jù)情況還可以實現(xiàn)onDraw等方法
19-1-1 知道流布局么,讓你實現(xiàn)怎么實現(xiàn),大體講一講?(A)
通過onMeasure對內(nèi)部組件進(jìn)行遍歷計算寬度和高度,如果內(nèi)部組件的寬度和(包括margin)比父類給予的寬度大了就開第二行進(jìn)行計算,并疊加高度,.依次來進(jìn)行計算控件的寬高,然后調(diào)用setMeasureDimension.
通過onLayout來計算坐標(biāo)點,計算方式跟onMeasure方式相同,只是寬高存儲改為坐標(biāo)存儲.
20. 題外問題
- 20-1 為什么android的包名用com.xxxx.xxxx方式?(C)
java項目遺留下來的不成文的規(guī)定,習(xí)慣問題,com代表公司,org代表個人,也完全可以用自己喜歡的方式,主要就是為了防止出現(xiàn)包名重復(fù)出現(xiàn)問題.
21.自定義問題
- 21-1 五個控件娘锁,左右頂格牙寞,距離相等,horizental
22.什么叫事件驅(qū)動
通過行為動作比如一個點擊莫秆,一個觸摸等等间雀,程序就會給出相應(yīng)的反饋,就是事件驅(qū)動镊屎。