最近開始踏上找工作的步伐,總結(jié)一下常見的問題
1.Android的三類動畫及優(yōu)缺點
(1)Frame Animation(幀動畫)主要用于播放一幀幀準(zhǔn)備好的圖片赫舒,類似GIF圖片悍及,優(yōu)點是使用簡單方便、缺點是需要事先準(zhǔn)備好每一幀圖片接癌;
(2)Tween Animation(補(bǔ)間動畫)僅需定義開始與結(jié)束的關(guān)鍵幀心赶,而變化的中間幀由系統(tǒng)補(bǔ)上,優(yōu)點是不用準(zhǔn)備每一幀缺猛,缺點是只改變了對象繪制缨叫,而沒有改變View本身屬性。因此如果改變了按鈕的位置荔燎,還是需要點擊原來按鈕所在位置才有效耻姥。
(3)Property Animation(屬性動畫)是3.0后推出的動畫,優(yōu)點是使用簡單有咨、降低實現(xiàn)的復(fù)雜度琐簇、直接更改對象的屬性、幾乎可適用于任何對象而僅非View類座享,缺點是需要3.0以上的API支持婉商,限制較大!
2.handler機(jī)制的原理
3.說說MVC模式的原理渣叛,它在android中的運用
MVC全名是ModelViewController丈秩,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設(shè)計典范淳衙,用一種業(yè)務(wù)邏輯蘑秽、數(shù)據(jù)、界面顯示分離的方法組織代碼箫攀,將業(yè)務(wù)邏輯聚集到一個部件里面肠牲,在改進(jìn)和個性化定制界面及用戶交互的同時,不需要重新編寫業(yè)務(wù)邏輯匠童。其中M層處理數(shù)據(jù)埂材,業(yè)務(wù)邏輯等;V層處理界面的顯示結(jié)果汤求;C層起到橋梁的作用俏险,來控制V層和M層通信以此來達(dá)到分離視圖顯示和業(yè)務(wù)邏輯層严拒。
采用MVC模式的好處是便于UI界面部分的顯示和業(yè)務(wù)邏輯,數(shù)據(jù)處理分開竖独。
4.讓Activity變成一個窗口
讓Activity變成一個窗口:Activity屬性設(shè)定
講點輕松的吧,可能有人希望做出來的應(yīng)用程序是一個漂浮在手機(jī)主界面的東西裤唠,那么很
簡單你只需要設(shè)置 一下Activity的主題就可以了在AndroidManifest.xml 中定義 Activity的地方一句話:
Xml代碼
android :theme="@android:style/Theme.Dialog"
android:theme="@android:style/Theme.Dialog"
這就使你的應(yīng)用程序變成對話框的形式彈出來了,或者透明的主題
Xml代碼
android:theme="@android:style/Theme.Translucent"
android:theme="@android:style/Theme.Translucent"
5.簡述activity的幾種啟動模式莹痢,并舉例說明他的用處种蘸。
Activity的啟動模式主要有以下四種
Standard、singleTop竞膳、singleTask航瞭、singleInstance
Standard:默認(rèn)模式,可以不用寫配置坦辟。在這個模式下刊侯,都會默認(rèn)創(chuàng)建一個新的實例。因此锉走,在這種模式下滨彻,可以有多個相同的實例,也允許多個相同Activity疊加挪蹭。
singleTop:可以有多個實例亭饵,但是不允許多個相同Activity疊加。即梁厉,如果Activity在棧頂?shù)臅r候辜羊,啟動相同的Activity,不會創(chuàng)建新的實例懂算,而會調(diào)用其onNewIntent方法只冻。
singleTask:只有一個實例庇麦。在同一個應(yīng)用程序中啟動他的時候计技,若Activity不存在,則會在當(dāng)前task創(chuàng)建一個新的實例山橄,若存在垮媒,則會把task中在其之上的其它Activity destory掉并調(diào)用它的onNewIntent方法。
例如:現(xiàn)在棧的情況為:A B C D航棱。B的Launch mode為singleTask睡雇,此時D通過Intent跳轉(zhuǎn)到B,則棧的情況變成了:A
B饮醇。而C和D被彈出銷毀了它抱,也就是說位于B之上的實例都被銷毀了。
注意:singleTask模式的Activity不管是位于棧頂還是棧底朴艰,再次運行這個Activity時木柬,都會destory掉它上面的Activity來保證整個棧中只有一個自己右莱,切記切記
- singleInstance:只有一個實例廓译,并且這個實例獨立運行在一個task中,這個task只有這個實例歌径,不允許有別的Activity存在。
6.你后臺的Activity被系統(tǒng)回收怎么辦
onSaveInstanceState方法
當(dāng)你的程序中某一個Activity A 在運行時中亲茅,主動或被動地運行另一個新的Activity B
這個時候A會執(zhí)行
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);
}
B 完成以后又會來找A, 這個時候就有兩種情況回铛,一種是A被回收,一種是沒有被回收克锣,被回收的A就要重新調(diào)用onCreate()方法茵肃,不同于直接啟動的是這回onCreate()里是帶上參數(shù)savedInstanceState,沒被收回的就還是onResume就好了袭祟。
if(savedInstanceState != null){
long id = savedInstanceState.getLong("id");
}
就像官方的Notepad教程 里的情況免姿,你正在編輯某一個note,突然被中斷榕酒,那么就把這個note的id記住胚膊,再起來的時候就可以根據(jù)這個id去把那個note取出來,程序就完整一些想鹰。這也是看你的應(yīng)用需不需要保存什么紊婉,比如你的界面就是讀取一個列表,那就不需要特殊記住什么辑舷,哦喻犁, 沒準(zhǔn)你需要記住滾動條的位置...
以及看視頻時,有橫屏切換到豎屏何缓。
7.如何退出Activity?如何安全退出已調(diào)用多個Activity的Application?
-
對于單一Activity的應(yīng)用來說肢础,直接finish()即可。
-
調(diào)用多個Activity的Application
- 1碌廓、拋異常強(qiáng)制退出:
該方法通過拋異常传轰,使程序ForceClose。
驗證可以谷婆,但是慨蛙,需要解決的問題是,如何使程序結(jié)束掉纪挎,而不彈出Force Close的窗口期贫。 - 2、記錄打開的Activity:
每打開一個Activity异袄,就記錄下來通砍。在需要退出時,關(guān)閉每一個Activity即可烤蜕。 - 3封孙、發(fā)送特定廣播:
在需要結(jié)束應(yīng)用時垢揩,發(fā)送一個特定的廣播,每個Activity收到廣播后敛瓷,關(guān)閉即可叁巨。 - 4、遞歸退出
在打開新的Activity時使用startActivityForResult呐籽,然后自己加標(biāo)志锋勺,在onActivityResult中處理,遞歸關(guān)閉狡蝶。
- 1碌廓、拋異常強(qiáng)制退出:
A Activity ->> B Activty A 中:
startActivtiyForResult();
onActivtyResult()中處理
B中:
setResult();
finish();
8.請介紹下Android中常用的布局
- 線性布局LinearLayout
- 相對布局RelativeLayout
- 幀布局FrameLayout
- 表格布局TableLayou
以及一個不怎么常用的布局:絕對布局AbsoluteLayout
9.請介紹下Android的數(shù)據(jù)存儲方式庶橱。
五種:
SharedPreferences存儲數(shù)據(jù);文件存儲數(shù)據(jù)贪惹;SQLite數(shù)據(jù)庫存儲數(shù)據(jù)苏章;ContentProvider存儲數(shù)據(jù);網(wǎng)絡(luò)存儲數(shù)據(jù)奏瞬。
10.請介紹下ContentProvider是如何實現(xiàn)數(shù)據(jù)共享的
Android提供了ContentProvider枫绅,一個程序可以通過實現(xiàn)一個ContentProvider的抽象接口將自己的數(shù)據(jù)完全暴露出去,而且ContentProviders是以類似數(shù)據(jù)庫中表的方式將數(shù)據(jù)暴露硼端,也就是說ContentProvider就像一個“數(shù)據(jù)庫”并淋。那么外界獲取其提供的數(shù)據(jù),也就應(yīng)該與從數(shù)據(jù)庫中獲取數(shù)據(jù)的操作基本一樣珍昨,只不過是采用URI來表示外界需要訪問的“數(shù)據(jù)庫”县耽。外部訪問通過ContentResolver去訪問并操作這些被暴露的數(shù)據(jù)。
11.AsyncTask 的異步機(jī)制和普通線程有什么區(qū)別镣典,分別有哪些優(yōu)缺點兔毙。
Asynctask就是thread+handler+線程池。
如果我們創(chuàng)建大量的(特別是在短時間內(nèi)兄春,持續(xù)的創(chuàng)建生命周期較長的線程)野生線程澎剥,往往會出現(xiàn)如下兩方面的問題:
- 每個線程的創(chuàng)建與銷毀(特別是創(chuàng)建)的資源開銷是非常大的;
- 分享主線程的系統(tǒng)資源神郊,從而會使主線程因資源受限而導(dǎo)致應(yīng)用性能降低肴裙。
各位開發(fā)一線的前輩們?yōu)榱私鉀Q這個問題,引入了線程池(ThreadPool)的概念涌乳,也就是把這些野生的線程圈養(yǎng)起來,統(tǒng)一的管理他們甜癞。線程是稀缺資源夕晓,如果無限制的創(chuàng)建,不僅會消耗系統(tǒng)資源悠咱,還會降低系統(tǒng)的穩(wěn)定性蒸辆,使用線程池可以進(jìn)行統(tǒng)一的分配征炼,調(diào)優(yōu)和監(jiān)控。
AsyncTask詳細(xì)解答
AsyncTask的缺陷
12.注冊廣播有幾種方式躬贡,這些方式有何優(yōu)缺點?請談?wù)凙ndroid引入廣播機(jī)制的用意谆奥。
在android下,要想接受廣播信息拂玻,那么這個廣播接收器就得我們自己來實現(xiàn)了酸些,我們可以繼承BroadcastReceiver,就可以有一個廣播接收器了檐蚜。有個接收器還不夠魄懂,我們還得重寫B(tài)roadcastReceiver里面的onReceiver方法,然后注冊廣播闯第。
有兩種方式:
- 一種是代碼動態(tài)注冊
生成廣播處理
smsBroadCastReceiver = new SmsBroadCastReceiver();
實例化過濾器并設(shè)置要過濾的廣播
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
注冊廣播
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver, intentFilter);
2.還有靜態(tài)AndroidManifest.xml中配置廣播
<!--廣播注冊-->
<receiver android:name=".SmsBroadCastReceiver">
<intent-filter android:priority="20">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
兩種注冊類型的區(qū)別以及優(yōu)缺點是:
1.第一種不是常駐型廣播市栗,也就是說廣播跟隨程序的生命周期,在靈活性方面有很大的優(yōu)勢咳短,但是缺點也很明顯填帽,即必須在程序啟動后才能接收廣播。
2.第二種是常駐型咙好,也就是說當(dāng)應(yīng)用程序關(guān)閉后盲赊,如果有信息廣播來,程序也會被系統(tǒng)調(diào)用自動運行敷扫。
13.AIDL的全稱是什么?如何工作?能處理哪些類型的數(shù)據(jù)?
AIDL的全稱:Android Interface Definition Language,即Android接口定義語言哀蘑。
14.什么是ANR 如何避免它?
ANR的定義:在Android上,如果你的應(yīng)用程序有一段時間響應(yīng)不夠靈敏葵第,系統(tǒng)會向用戶顯示一個對話框绘迁,這個對話框稱作應(yīng)用程序無響應(yīng)(ANR:ApplicationNotResponding)對話框。用戶可以選擇讓程序繼續(xù)運行卒密,但是缀台,他們在使用你的應(yīng)用程序時,并不希望每次都要處理這個對話框哮奇。因此膛腐,在程序里對響應(yīng)性能的設(shè)計很重要,這樣鼎俘,系統(tǒng)不會顯示ANR給用戶哲身。
如何避免:運行在主線程里的任何方法都盡可能少做事情,耗時操作需開辟一個子線程贸伐。
IntentReceiver執(zhí)行時間的特殊限制意味著它應(yīng)該做:在后臺里做小的勘天、瑣碎的工作如保存設(shè)定或者注冊一個
Notification。和在主線程里調(diào)用的其它方法一樣,應(yīng)用程序應(yīng)該避免在BroadcastReceiver里做耗時的操作或計算脯丝。但不再是在子線程里做這些任務(wù)(因為BroadcastReceiver的生命周期短)商膊,替代的是,如果響應(yīng)Intent廣播需要執(zhí)行一個耗時的動作的話宠进,應(yīng)用程序應(yīng)該啟動一個Service晕拆。
15.IntentService有何優(yōu)點?
IntentService使用隊列的方式將請求的Intent加入隊列,然后開啟一個workerthread(線程)來處理隊列中的Intent材蹬,對于異步的startService請求实幕,IntentService會處理完成一個之后再處理第二個,每一個請求都會在一個單獨的worker thread中處理赚导,不會阻塞應(yīng)用程序的主線程茬缩。
16.橫豎屏切換時候activity的生命周期?
- 不設(shè)置Activity的android:configChanges時,切屏?xí)匦抡{(diào)用各個生命周期吼旧,切橫屏?xí)r會執(zhí)行一次凰锡,切豎屏?xí)r會執(zhí)行兩次
- 設(shè)置Activity的android:configChanges="orientation"時,切屏還是會重新調(diào)用各個生命周期圈暗,切橫掂为、豎屏?xí)r只會執(zhí)行一次
- 設(shè)置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調(diào)用各個生命周期员串,只會執(zhí)行onConfigurationChanged方法
總結(jié)一下整個Activity的生命周期
- 當(dāng)前Activity產(chǎn)生事件彈出Toast和AlertDialog的時候Activity的生命周期不會有改變
- Activity運行時按下HOME鍵(跟被完全覆蓋是一樣的):onSaveInstanceState --> onPause --> onStop onRestart -->onStart--->onResume
- Activity未被完全覆蓋只是失去焦點:onPause--->onResume
以及引申問題:豎屏Activity跳轉(zhuǎn)到橫屏Activity(或橫豎屏切換)勇哗,back返回黑屏解決
解決辦法:
//在豎屏的Activity中添加:
android:configChanges="orientation"
android:screenOrientation="portrait"
17.Android基本架構(gòu)
Android其本質(zhì)就是在標(biāo)準(zhǔn)的Linux系統(tǒng)上增加了Java虛擬機(jī)Dalvik,并在Dalvik虛擬機(jī)上搭建了一個JAVA的application framework寸齐,所有的應(yīng)用程序都是基于JAVA的application framework之上欲诺。
Android主要應(yīng)用于ARM平臺,但不僅限于ARM渺鹦,通過編譯控制扰法,在X86、MAC等體系結(jié)構(gòu)的機(jī)器上同樣可以運行毅厚。
藍(lán)色的代表java程序塞颁,黃色的代碼為運行JAVA程序而實現(xiàn)的虛擬機(jī),綠色部分為C/C++語言編寫的程序庫吸耿,紅色的代碼內(nèi)核(linux內(nèi)核+driver)祠锣。在ApplicationFramework之下,由C/C++的程序庫組成咽安,通過JNI完成從JAVA到C的調(diào)用伴网。
android分為四個層,從高層到低層分別是應(yīng)用程序?qū)?/strong>板乙、應(yīng)用程序框架層是偷、系統(tǒng)運行庫層和linux核心層拳氢。
各層詳細(xì)參考這里
18.什么是Service以及描述下它的生命周期募逞。Service有哪些啟動方法蛋铆,有什么區(qū)別,怎樣停 用Service放接?
Service即服務(wù)刺啦,可以形象的理解為不可視化的Activity,它是Android中實現(xiàn)程序后臺運行的解決方案纠脾,它適合用于去執(zhí)行那些不需要與用戶交互而且還要求長期運行的程序玛瘸。
服務(wù)的生命周期如圖
注:一個服務(wù)在調(diào)用了startService()方法后也可以調(diào)用bindservice()方法,那么如果要銷毀的時候需要同時調(diào)用stopService()和unbindService()方法苟蹈,onDestroy()方法才會執(zhí)行糊渊。
19.Intent傳遞數(shù)據(jù)時,可以傳遞哪些類型數(shù)據(jù)慧脱?
Intent/Bundle支持傳遞基本類型的數(shù)據(jù)和基本類型的數(shù)組數(shù)據(jù)渺绒,以及String/CharSequence類型的數(shù)據(jù)和String/CharSequence類型的數(shù)組數(shù)據(jù)。而對于其它類型的數(shù)據(jù)貌似無能為力菱鸥,其實不然宗兼,我們可以在Intent/Bundle的API中看到Intent/Bundle還可以傳遞Parcelable(包裹化,郵包)和Serializable(序列化)類型的數(shù)據(jù)氮采,以及它們的數(shù)組/列表數(shù)據(jù)殷绍。
20.描述下Intent和 Intent Filter.
- Intent是Android程序中各個組件之間進(jìn)行交互的一種重要方式,充當(dāng)一個信使的作用鹊漠。
- Intent Filter 則是一個意圖過濾器主到。一個應(yīng)用程序開發(fā)完成后,需要告訴Android系統(tǒng)自己能夠處理哪些隱形的Intent請求躯概,這就需要聲明IntentFilter登钥。
另附:如果說Intent是一個對動作和行為的抽象描述,負(fù)責(zé)組件之間程序之間進(jìn)行消息傳遞楞陷。那么Broadcast Receiver組件就提供了一種把Intent作為一個消息廣播出去怔鳖,由所有對其感興趣的程序?qū)ζ渥鞒龇磻?yīng)的機(jī)制。
21.ListView如何提高其效率固蛾?
- 在適配器adapter中采用viewHolder模式以及用convertView回收視圖结执。
- 預(yù)先縮放到視圖大小,避免圖片實時縮放艾凯。
圖片加載的內(nèi)存管理
22.Android系統(tǒng)中GC(垃圾回收器)什么情況下會出現(xiàn)內(nèi)存泄露呢献幔?
Java 內(nèi)存泄露的根本原因就是 保存了不可能再被訪問的變量類型的引用。
23.Android UI中的View如何刷新趾诗。
如果只是單純的想要更新UI而不涉及到多線程的話蜡感,使用View.post()就可以了; 詳細(xì)解答
需要另開線程處理數(shù)據(jù)以免阻塞UI線程蹬蚁,像是IO操作或者是循環(huán),可以使用Activity.runOnUiThread();
如果需要傳遞狀態(tài)值等信息郑兴,像是藍(lán)牙編程中的socket連接犀斋,就需要利用狀態(tài)值來提示連接狀態(tài)以及做相應(yīng)的處理,就需要使用Handler + Thread的方式;
如果是后臺任務(wù)情连,像是下載任務(wù)等叽粹,就需要使用AsyncTask。
24.寫出幾種你認(rèn)為可以提高Android程序運行效率的方法却舀?
- 避免多余對象的創(chuàng)建
- 使用靜態(tài)方法定義不會訪問到對象內(nèi)部的函數(shù)
- 使用Static Final定義常量
- 避免在類內(nèi)部使用get/set方法
- ArrayList不使用增強(qiáng)型for循環(huán)
- 使用包級訪問代替私有內(nèi)聯(lián)類的訪問
- 使用double代替float
- 優(yōu)先使用第三方類庫而不是重復(fù)造輪子
- 謹(jǐn)慎使用NDK
- 不要執(zhí)迷于性能神話
- 量化性能以及優(yōu)化方法性能的量化虫几,從而選擇合適的優(yōu)化方式
詳細(xì)的介紹在此
25.ArrayList和LinkedList的區(qū)別
1.ArrayList是實現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu)挽拔。
2.對于隨機(jī)訪問get和set辆脸,ArrayList覺得優(yōu)于LinkedList,因為LinkedList要移動指針螃诅。
3.對于新增和刪除操作add和remove啡氢,LinedList比較占優(yōu)勢,因為ArrayList要移動數(shù)據(jù)州刽。
4.查找操作indexOf,lastIndexOf,contains等空执,兩者差不多。
5.隨機(jī)查找指定節(jié)點的操作get穗椅,ArrayList速度要快于LinkedList.
GitHub上面一篇匯總文章辨绊,很nice
我是文