[TOC]
以后更新的面試題會(huì)放在頂部
靜態(tài)內(nèi)部類、內(nèi)部類、匿名內(nèi)部類巡语,為什么內(nèi)部類會(huì)持有外部類的引用?持有的引用是this淮菠?還是其它男公?
靜態(tài)內(nèi)部類:使用static修飾的內(nèi)部類
匿名內(nèi)部類:使用new生成的內(nèi)部類
因?yàn)閮?nèi)部類的產(chǎn)生依賴于外部類,持有的引用是類名.this合陵。
事件分發(fā)機(jī)制
對于一個(gè)根ViewGroup來說,發(fā)生點(diǎn)擊事件首先調(diào)用dispatchTouchEvent
如果這個(gè)ViewGroup的onIterceptTouchEvent返回true就表示它要攔截當(dāng)前事件,接著這個(gè)ViewGroup的onTouchEvent就會(huì)被調(diào)用.如果onIterceptTouchEvent返回false,那么就會(huì)繼續(xù)向下調(diào)用子View的dispatchTouchEvent方法
當(dāng)一個(gè)View需要處理事件的時(shí)候,如果它沒有設(shè)置onTouchListener,那么直接調(diào)用onTouchEvent.如果設(shè)置了Listenter 那么就要看Listener的onTouch方法返回值.為true就不調(diào),為false就調(diào)onTouchEvent
View的默認(rèn)實(shí)現(xiàn)會(huì)在onTouchEvent里面把touch事件解析成Click之類的事件
點(diǎn)擊事件傳遞順序 Activity -> Window -> View
一旦一個(gè)元素?cái)r截了某事件,那么一個(gè)事件序列里面后續(xù)的Move,Down事件都會(huì)交給它處理.并且它的onInterceptTouchEvent不會(huì)再調(diào)用
View的onTouchEvent默認(rèn)都會(huì)消耗事件,除非它的clickable和longClickable都是false(不可點(diǎn)擊),但是enable屬性不會(huì)影響
View本身是沒有onInterceptTouchEvent()方法的, 這個(gè)方法在ViewGroup中
計(jì)算機(jī)網(wǎng)絡(luò)的ISO模型分層
什么是Socket ?
我們知道兩個(gè)進(jìn)程如果需要進(jìn)行通訊最基本的一個(gè)前提能能夠唯一的標(biāo)示一個(gè)進(jìn)程枢赔,在本地進(jìn)程通訊中我們可以使用PID來唯一標(biāo)示一個(gè)進(jìn)程,但PID只在本地唯一拥知,網(wǎng)絡(luò)中的兩個(gè)進(jìn)程PID沖突幾率很大踏拜,這時(shí)候我們需要另辟它徑了,我們知道IP層的ip地址可以唯一標(biāo)示主機(jī)低剔,而TCP層協(xié)議和端口號可以唯一標(biāo)示主機(jī)的一個(gè)進(jìn)程速梗,這樣我們可以利用ip地址+協(xié)議+端口號唯一標(biāo)示網(wǎng)絡(luò)中的一個(gè)進(jìn)程。
能夠唯一標(biāo)示網(wǎng)絡(luò)中的進(jìn)程后襟齿,它們就可以利用socket進(jìn)行通信了镀琉,什么是socket呢?我們經(jīng)常把socket翻譯為套接字蕊唐,socket是在應(yīng)用層和傳輸層之間的一個(gè)抽象層,它把TCP/IP層復(fù)雜的操作抽象為幾個(gè)簡單的接口供應(yīng)用層調(diào)用已實(shí)現(xiàn)進(jìn)程在網(wǎng)絡(luò)中通信烁设。
socket起源于UNIX替梨,在Unix一切皆文件哲學(xué)的思想下,socket是一種"打開—讀/寫—關(guān)閉"模式的實(shí)現(xiàn)装黑,服務(wù)器和客戶端各自維護(hù)一個(gè)"文件"副瀑,在建立連接打開后,可以向自己文件寫入內(nèi)容供對方讀取或者讀取對方內(nèi)容恋谭,通訊結(jié)束時(shí)關(guān)閉文件糠睡。
TCP協(xié)議的三次握手
第一次握手:客戶端嘗試連接服務(wù)器,向服務(wù)器發(fā)送syn包(同步序列編號Synchronize Sequence Numbers)疚颊,syn=j狈孔,客戶端進(jìn)入SYN_SEND狀態(tài)等待服務(wù)器確認(rèn)
第二次握手:服務(wù)器接收客戶端syn包并確認(rèn)(ack=j+1),同時(shí)向客戶端發(fā)送一個(gè)SYN包(syn=k)材义,即SYN+ACK包均抽,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài)
第三次握手:第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=k+1)其掂,此包發(fā)送完畢油挥,客戶端和服務(wù)器進(jìn)入ESTABLISHED狀態(tài),完成三次握手
定睛一看,服務(wù)器socket與客戶端socket建立連接的部分其實(shí)就是大名鼎鼎的三次握手
Android的四大組件是哪些 ?
Activity:Activity是Android程序與用戶交互的窗口深寥,是Android構(gòu)造塊中最基本的一種攘乒,它需要為保持各界面的狀態(tài),做很多持久化的事情惋鹅,妥善管理生命周期以及一些跳轉(zhuǎn)邏輯则酝。
service:后臺(tái)服務(wù)于Activity,封裝有一個(gè)完整的功能邏輯實(shí)現(xiàn). Service可以在很多場合的應(yīng)用中使用负饲,比如播放多媒體的時(shí)候用戶啟動(dòng)了其他Activity這個(gè)時(shí)候程序要在后臺(tái)繼續(xù)播放堤魁,比如檢測SD卡上文件的變化,再或者在后臺(tái)記錄你地理信息位置的改變等等返十,總之服務(wù)總是藏在后臺(tái)的妥泉。
Content Provider:是Android提供的第三方應(yīng)用數(shù)據(jù)的訪問方案,可以派生Content Provider類洞坑,對外提供數(shù)據(jù)盲链,可以像數(shù)據(jù)庫一樣進(jìn)行選擇排序,屏蔽內(nèi)部數(shù)據(jù)的存儲(chǔ)細(xì)節(jié)迟杂,向外提供統(tǒng)一的接口模型刽沾,大大簡化上層應(yīng)用,對數(shù)據(jù)的整合提供了更方便的途徑
BroadCast Receiver:接受一種或者多種Intent作觸發(fā)事件排拷,接受相關(guān)消息侧漓,做一些簡單處理,轉(zhuǎn)換成一條Notification监氢,統(tǒng)一了Android的事件廣播模型
請介紹下Android中常用的四種布局
- FrameLayout 所有東西依次都放在左上角布蔗,會(huì)重疊,這個(gè)布局比較簡單浪腐,也只能放一點(diǎn)比較簡單的東西纵揍。
- LinerLayout 線性布局,每一個(gè)LinearLayout里面又可分為垂直布局(android:orientation="vertical")和水平布局(android:orientation="horizontal" )议街。當(dāng)垂直布局時(shí)泽谨,每一行就只有一個(gè)元素,多個(gè)元素依次垂直往下特漩;水平布局時(shí)吧雹,只有一行,每一個(gè)元素依次向右排列涂身。
- RelativeLayout 相對布局可以理解為某一個(gè)元素為參照物吮炕,來定位的布局方式。
- TableLayout 表格布局.
android中的動(dòng)畫有哪幾類访得,它們的特點(diǎn)和區(qū)別是什么
三種, Tween(補(bǔ)間動(dòng)畫), Frame(幀動(dòng)畫)和屬性動(dòng)畫.
Tween動(dòng)畫龙亲,這種實(shí)現(xiàn)方式可以使視圖組件移動(dòng)陕凹、放大、縮小以及產(chǎn)生透明度的變化;
Frame動(dòng)畫,傳統(tǒng)的動(dòng)畫方法,通過順序的播放排列好的圖片來實(shí)現(xiàn)启摄,類似電影。
屬性動(dòng)畫, 通過改變某個(gè)控件的屬性值來實(shí)現(xiàn)動(dòng)畫效果
android中有哪幾種解析xml的類佑女?官方推薦哪種?以及它們的原理和區(qū)別
XML解析主要有三種方式谈竿,SAX团驱、DOM、PULL空凸。
常規(guī)在PC上開發(fā)我們使用Dom相對輕松些嚎花,但一些性能敏感的數(shù)據(jù)庫或手機(jī)上還是主要采用SAX方式,SAX讀取是單向的呀洲,優(yōu)點(diǎn):不占內(nèi)存空間紊选、解析屬性方便,但缺點(diǎn)就是對于套嵌多個(gè)分支來說處理不是很方便道逗。
而DOM方式會(huì)把整個(gè)XML文件加載到內(nèi)存中去兵罢,但是提醒大家該方法在查找方面可以和XPath很好的結(jié)合如果數(shù)據(jù)量不是很大推薦使用。
而PULL常常用在J2ME對于節(jié)點(diǎn)處理比較好滓窍,類似SAX方式卖词,同樣很節(jié)省內(nèi)存,在J2ME中我們經(jīng)常使用的KXML庫來解析吏夯。
ListView的優(yōu)化方案
復(fù)用convertView
給contentView設(shè)置tag(setTag())坏平,傳入一個(gè)viewHolder對象,用于緩存要顯示的數(shù)據(jù)锦亦,可以達(dá)到圖像數(shù)據(jù)異步加載的效果。
設(shè)置ListView的高度為 確定值或match_parent
如果listview需要顯示的item很多令境,就要考慮分頁加載杠园。
請介紹下Android的數(shù)據(jù)存儲(chǔ)方式。
使用SharedPreferences存儲(chǔ)數(shù)據(jù)舔庶;文件存儲(chǔ)數(shù)據(jù)抛蚁;SQLite數(shù)據(jù)庫存儲(chǔ)數(shù)據(jù);使用ContentProvider存儲(chǔ)數(shù)據(jù)惕橙;網(wǎng)絡(luò)存儲(chǔ)數(shù)據(jù)瞧甩;
activity的啟動(dòng)模式有哪些?是什么含義弥鹦?
在android里肚逸,有4種activity的啟動(dòng)模式爷辙,分別為:
“standard” (默認(rèn)): Activity無限壓棧, 不做任何處理
“singleTop” : 如果啟動(dòng)activity時(shí)發(fā)現(xiàn)它當(dāng)前已經(jīng)在棧頂則不會(huì)重新創(chuàng)建一個(gè)實(shí)例, 如果你啟動(dòng)的那個(gè)activity不再棧頂?shù)脑捑蜁?huì)重新創(chuàng)建一個(gè)activity實(shí)例朦促。
“singleTask” : 當(dāng)你的activity設(shè)置為SingleTask時(shí)膝晾,每次啟動(dòng)你的activity的時(shí)候 就會(huì)去棧里面是否存在這個(gè)activity的實(shí)例,如果存在則直接使用這個(gè)實(shí)例务冕,并把這個(gè)activity之上的所有其他的activity統(tǒng)統(tǒng)出棧血当,如果棧里面沒有這個(gè)activity的實(shí)例的話就創(chuàng)建一個(gè)該activity的實(shí)例。
“singleInstance” : 是其所在棧的唯一activity禀忆,它會(huì)每次都被重用臊旭。
activity在屏幕旋轉(zhuǎn)時(shí)的生命周期
不設(shè)置Activity的android:configChanges時(shí),切屏?xí)匦抡{(diào)用各個(gè)生命周期箩退,切橫屏?xí)r會(huì)執(zhí)行一次离熏,切豎屏?xí)r會(huì)執(zhí)行兩次;設(shè)置Activity的android:configChanges="orientation"時(shí)乏德,切屏還是會(huì)重新調(diào)用各個(gè)生命周期撤奸,切橫、豎屏?xí)r只會(huì)執(zhí)行一次喊括;設(shè)置Activity的android:configChanges="orientation|keyboardHidden"時(shí)胧瓜,切屏不會(huì)重新調(diào)用各個(gè)生命周期,只會(huì)執(zhí)行onConfigurationChanged方法
如何啟用Service郑什,如何停用Service
服務(wù)的開發(fā)比較簡單府喳,如下:
第一步:繼承Service類
public classSMSService extends Service {}
第二步:在AndroidManifest.xml文件中的<application>節(jié)點(diǎn)里對服務(wù)進(jìn)行配置:
<serviceandroid:name=".SMSService" />
服務(wù)不能自己運(yùn)行,需要通過調(diào)用Context.startService()或Context.bindService()方法啟動(dòng)服務(wù)蘑拯。這兩個(gè)方法都可以啟動(dòng)Service钝满,但是它們的使用場合有所不同。使用startService()方法啟用服務(wù)申窘,調(diào)用者與服務(wù)之間沒有關(guān)連弯蚜,即使調(diào)用者退出了,服務(wù)仍然運(yùn)行剃法。使用bindService()方法啟用服務(wù)碎捺,調(diào)用者與服務(wù)綁定在了一起,調(diào)用者一旦退出贷洲,服務(wù)也就終止收厨,大有“不求同時(shí)生,必須同時(shí)死”的特點(diǎn)优构。
如果打算采用Context.startService()方法啟動(dòng)服務(wù)诵叁,在服務(wù)未被創(chuàng)建時(shí),系統(tǒng)會(huì)先調(diào)用服務(wù)的onCreate()方法钦椭,接著調(diào)用onStart()方法拧额。如果調(diào)用startService()方法前服務(wù)已經(jīng)被創(chuàng)建碑诉,多次調(diào)用startService()方法并不會(huì)導(dǎo)致多次創(chuàng)建服務(wù),但會(huì)導(dǎo)致多次調(diào)用onStart()方法势腮。采用startService()方法啟動(dòng)的服務(wù)联贩,只能調(diào)用Context.stopService()方法結(jié)束服務(wù),服務(wù)結(jié)束時(shí)會(huì)調(diào)用onDestroy()方法捎拯。
如果打算采用Context.bindService()方法啟動(dòng)服務(wù)泪幌,在服務(wù)未被創(chuàng)建時(shí),系統(tǒng)會(huì)先調(diào)用服務(wù)的onCreate()方法署照,接著調(diào)用onBind()方法祸泪。這個(gè)時(shí)候調(diào)用者和服務(wù)綁定在一起,調(diào)用者退出了建芙,系統(tǒng)就會(huì)先調(diào)用服務(wù)的onUnbind()方法没隘,接著調(diào)用onDestroy()方法。如果調(diào)用bindService()方法前服務(wù)已經(jīng)被綁定禁荸,多次調(diào)用bindService()方法并不會(huì)導(dǎo)致多次創(chuàng)建服務(wù)及綁定(也就是說onCreate()和onBind()方法并不會(huì)被多次調(diào)用)右蒲。如果調(diào)用者希望與正在綁定的服務(wù)解除綁定,可以調(diào)用unbindService()方法赶熟,調(diào)用該方法也會(huì)導(dǎo)致系統(tǒng)調(diào)用服務(wù)的onUnbind()-->onDestroy()方法瑰妄。
服務(wù)常用生命周期回調(diào)方法如下:
onCreate() 該方法在服務(wù)被創(chuàng)建時(shí)調(diào)用,該方法只會(huì)被調(diào)用一次映砖,無論調(diào)用多少次startService()或bindService()方法间坐,服務(wù)也只被創(chuàng)建一次。
onDestroy()該方法在服務(wù)被終止時(shí)調(diào)用邑退。
與采用Context.startService()方法啟動(dòng)服務(wù)有關(guān)的生命周期方法
onStart() 只有采用Context.startService()方法啟動(dòng)服務(wù)時(shí)才會(huì)回調(diào)該方法竹宋。該方法在服務(wù)開始運(yùn)行時(shí)被調(diào)用。多次調(diào)用startService()方法盡管不會(huì)多次創(chuàng)建服務(wù)地技,但onStart() 方法會(huì)被多次調(diào)用蜈七。
與采用Context.bindService()方法啟動(dòng)服務(wù)有關(guān)的生命周期方法
onBind()只有采用Context.bindService()方法啟動(dòng)服務(wù)時(shí)才會(huì)回調(diào)該方法。該方法在調(diào)用者與服務(wù)綁定時(shí)被調(diào)用莫矗,當(dāng)調(diào)用者與服務(wù)已經(jīng)綁定飒硅,多次調(diào)用Context.bindService()方法并不會(huì)導(dǎo)致該方法被多次調(diào)用。
onUnbind()只有采用Context.bindService()方法啟動(dòng)服務(wù)時(shí)才會(huì)回調(diào)該方法趣苏。該方法在調(diào)用者與服務(wù)解除綁定時(shí)被調(diào)用
注冊廣播有幾種方式,這些方式有何優(yōu)缺點(diǎn)梯轻?請談?wù)凙ndroid引入廣播機(jī)制的用意食磕。
答:首先寫一個(gè)類要繼承BroadcastReceiver
第一種:在清單文件中聲明,添加
<!--表示該receiver有效, 并且可以在外部訪問-->
<receiver
android:name=".MyReceiver1"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.lulu.action.MY_BROADCAST"/>
</intent-filter>
</receiver>
第二種使用代碼進(jìn)行注冊如:
//完成廣播注冊
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction("com.lulu.action.MY_BROADCAST");
registerReceiver(receiver2, filter);
}
//完成解除注冊
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver2);
}
兩種注冊類型的區(qū)別是:
1)第一種是常駐型,也就是說當(dāng)應(yīng)用程序關(guān)閉后喳挑,如果有信息廣播來彬伦,程序也會(huì)被系統(tǒng)調(diào)用自動(dòng)運(yùn)行滔悉。
2)第二種不是常駐型廣播,也就是說廣播跟隨程序的生命周期单绑。
Looper MessageQueue Message Handler的關(guān)系
Looper內(nèi)部有l(wèi)oop方法, 里面取的是Looper內(nèi)部的MessageQueue
MessageQueue內(nèi)部有Message
Handler內(nèi)部獲取當(dāng)前線程的Looper對象, 找到MessageQueue, Handler向其發(fā)送消息
loop一直在輪詢遍歷MessageQueue, 找到發(fā)來的handler對象并執(zhí)行dispatchMessage, 處理消息
mvc模式的原理
mvc是model,view,controller的縮寫回官,mvc包含三個(gè)部分:
模型(model)對象:是應(yīng)用程序的主體部分,所有的業(yè)務(wù)邏輯都應(yīng)該寫在該層搂橙。
視圖(view)對象:是應(yīng)用程序中負(fù)責(zé)生成用戶界面的部分歉提。也是在整個(gè)mvc架構(gòu)中用戶唯一可以看到的一層,接收用戶的輸入区转,顯示處理結(jié)果苔巨。
控制器(control)對象:是根據(jù)用戶的輸入,控制用戶界面數(shù)據(jù)顯示及更新model對象狀態(tài)的部分废离,控制器更重要的一種導(dǎo)航功能侄泽,響應(yīng)用戶出發(fā)的相關(guān)事件,交給m層處理蜻韭。
android鼓勵(lì)弱耦合和組件的重用悼尾,在android中mvc的具體體現(xiàn)如下:
1)視圖層(view):一般采用xml文件進(jìn)行界面的描述,使用的時(shí)候可以非常方便的引入肖方,當(dāng)然闺魏,如果你對android了解的比較的多了話,就一定可以想到在android中也可以使用JavaScript+html等的方式作為view層窥妇,當(dāng)然這里需要進(jìn)行java和javascript之間的通信舷胜,幸運(yùn)的是,android提供了它們之間非常方便的通信實(shí)現(xiàn)活翩。
2)控制層(controller):android的控制層的重任通常落在了眾多的acitvity的肩上烹骨,這句話也就暗含了不要在acitivity中寫代碼,要通過activity交割model業(yè)務(wù)邏輯層處理材泄,這樣做的另外一個(gè)原因是android中的acitivity的響應(yīng)時(shí)間是5s沮焕,如果耗時(shí)的操作放在這里,程序就很容易被回收掉拉宗。
3)模型層(model):對數(shù)據(jù)庫的操作峦树、對網(wǎng)絡(luò)等的操作都應(yīng)該在model里面處理,當(dāng)然對業(yè)務(wù)計(jì)算等操作也是必須放在的該層的旦事。
什么是ANR 如何避免它魁巩?
ANR:Application Not Responding。在 Android 上姐浮,如果你的應(yīng)用程序有一段時(shí)間響應(yīng)不夠靈敏谷遂,系統(tǒng)會(huì)向用戶顯示一個(gè)對話框,這個(gè)對話框稱作應(yīng)
用程序無響應(yīng)(ANR:Application Not Responding)對話框.
避免方法:Activity應(yīng)該在它的關(guān)鍵生命周期方法(如onCreate()和onResume())里盡可能少的去做創(chuàng)建操作和潛在的耗時(shí)操作卖鲤,例如網(wǎng)絡(luò)或數(shù)據(jù)庫操作肾扰,或者高耗時(shí)的計(jì)算如改變位圖尺寸畴嘶,應(yīng)該在子線程里(或者異步方式)來完成。主線程應(yīng)該為子線程提供一個(gè)Handler集晚,以便完成時(shí)能夠提交給主線程窗悯。
什么情況會(huì)導(dǎo)致Force Close ?如何避免偷拔?能否捕獲導(dǎo)致其的異常蒋院?
拋出運(yùn)行時(shí)異常時(shí)就會(huì)導(dǎo)致Force Close,比如空指針条摸、數(shù)組越界悦污、類型轉(zhuǎn)換異常等等。
捕獲:可以通過logcat查看拋出異常的代碼出現(xiàn)的位置钉蒲,然后到程序?qū)?yīng)代碼中進(jìn)行修改切端。
避免:編寫程序時(shí),要思維縝密顷啼,在可能出現(xiàn)異常的地方都作相應(yīng)的處理踏枣,增強(qiáng)程序的健壯性。
描述一下android的系統(tǒng)架構(gòu)
Android 架構(gòu):Linux Kernel(Linux內(nèi)核)钙蒙、Hardware Abstraction Layer(硬件抽象層)茵瀑、Libraries(系統(tǒng)運(yùn)行庫或者是c/c++ 核心庫)、Application Framework(開發(fā)框架包 )躬厌、Applications(核心應(yīng)用程序)
原來所說是四層: app马昨、Framework、lib扛施、kernel
請介紹下ContentProvider是如何實(shí)現(xiàn)數(shù)據(jù)共享的。
一個(gè)程序可以通過實(shí)現(xiàn)一個(gè)Content provider的抽象接口將自己的數(shù)據(jù)完全暴露出去疙渣,而且Contentproviders是以類似數(shù)據(jù)庫中表達(dá)方式將數(shù)據(jù)暴露匙奴。Content providers存儲(chǔ)和檢索數(shù)據(jù),通過它可以讓所有的應(yīng)用程序訪問到妄荔,這也是應(yīng)用程序之間唯一共享數(shù)據(jù)的方法泼菌。
要想使應(yīng)用程序的數(shù)據(jù)公開化,可通過2種方法:創(chuàng)建一個(gè)屬于你自己的Content provider或者將你的數(shù)據(jù)添加到一個(gè)已經(jīng)存在的Content provider中啦租,前提是有相同數(shù)據(jù)類型并且有寫入Contentprovider的權(quán)限哗伯。
如何通過一套標(biāo)準(zhǔn)及統(tǒng)一的接口獲取其他應(yīng)用程序暴露的數(shù)據(jù)?
Android提供了ContentResolver篷角,外界的程序可以通過ContentResolver接口訪問ContentProvider提供的數(shù)據(jù)焊刹。
Service和Thread的區(qū)別
答:servie是系統(tǒng)的組件,它由系統(tǒng)進(jìn)程托管(servicemanager);它們之間的通信類似于client和server伴澄,是一種輕量級的進(jìn)程間通訊(IPC (Inter-process communication))通信,這種通信的載體是binder阱缓,它是在linux層交換信息的一種ipc非凌。而thread是由本應(yīng)用程序托管。
1). Thread:Thread是程序執(zhí)行的最小單元荆针,它是分配CPU的基本單位敞嗡。可以用Thread 來執(zhí)行一些異步的操作航背。
2). Service:Service是android的一種機(jī)制喉悴,當(dāng)它運(yùn)行的時(shí)候如果是LocalService,那么對應(yīng)的Service 是運(yùn)行在主進(jìn)程的main 線程上的玖媚。如:onCreate箕肃,onStart這些函數(shù)在被系統(tǒng)調(diào)用的時(shí)候都是在主進(jìn)程的 main 線程上運(yùn)行的。如果是Remote Service今魔,那么對應(yīng)的Service 則是運(yùn)行在獨(dú)立進(jìn)程的main 線程上勺像。
既然這樣,那么我們?yōu)槭裁匆肧ervice 呢错森?其實(shí)這跟android 的系統(tǒng)機(jī)制有關(guān)吟宦,我們先拿Thread 來說。Thread的運(yùn)行是獨(dú)立于 Activity 的涩维,也就是說當(dāng)一個(gè)Activity 被 finish 之后殃姓,如果你沒有主動(dòng)停止Thread 或者Thread 里的 run方法沒有執(zhí)行完畢的話,Thread 也會(huì)一直執(zhí)行瓦阐。因此這里會(huì)出現(xiàn)一個(gè)問題:當(dāng)Activity 被 finish 之后蜗侈,你不再持有該Thread 的引用。另一方面垄分,你沒有辦法在不同的Activity 中對同一Thread 進(jìn)行控制宛篇。
舉個(gè)例子:如果你的Thread 需要不停地隔一段時(shí)間就要連接服務(wù)器做某種同步的話,該Thread 需要在Activity 沒有start的時(shí)候也在運(yùn)行薄湿。這個(gè)時(shí)候當(dāng)你start 一個(gè)Activity 就沒有辦法在該Activity 里面控制之前創(chuàng)建的Thread叫倍。因此你便需要?jiǎng)?chuàng)建并啟動(dòng)一個(gè)Service ,在Service 里面創(chuàng)建豺瘤、運(yùn)行并控制該Thread吆倦,這樣便解決了該問題(因?yàn)槿魏蜛ctivity 都可以控制同一Service,而系統(tǒng)也只會(huì)創(chuàng)建一個(gè)對應(yīng)Service 的實(shí)例)坐求。
因此你可以把Service 想象成一種消息服務(wù)蚕泽,而你可以在任何有Context 的地方調(diào)用Context.startService、Context.stopService、Context.bindService须妻,Context.unbindService仔蝌,來控制它,你也可以在Service 里注冊BroadcastReceiver荒吏,在其他地方通過發(fā)送broadcast 來控制它敛惊,當(dāng)然這些都是Thread 做不到的。
Android本身的api并未聲明會(huì)拋出異常绰更,則其在運(yùn)行時(shí)有無可能拋出runtime異常瞧挤,你遇到過嗎?諾有的話會(huì)導(dǎo)致什么問題儡湾?如何解決特恬?
答:會(huì),比如nullpointerException徐钠。我遇到過癌刽,比如textview.setText()時(shí),textview沒有初始化尝丐。會(huì)導(dǎo)致程序無法正常運(yùn)行出現(xiàn)forceclose妒穴。打開控制臺(tái)查看logcat信息找出異常信息并修改程序。
IntentService有何優(yōu)點(diǎn)?
Acitivity的進(jìn)程當(dāng)處理Intent的時(shí)候摊崭,會(huì)產(chǎn)生一個(gè)對應(yīng)的Service讼油; Android的進(jìn)程處理器現(xiàn)在會(huì)盡可能的不kill掉你;非常容易使用
如果后臺(tái)的Activity由于某原因被系統(tǒng)回收了呢簸,如何在被系統(tǒng)回收之前保存當(dāng)前狀態(tài)矮台?
答:重寫onSaveInstanceState()方法,在此方法中保存需要保存的數(shù)據(jù)根时,該方法將會(huì)在activity被回收之前調(diào)用瘦赫。通過重寫onRestoreInstanceState()方法可以從中提取保存好的數(shù)據(jù)
如何將一個(gè)Activity設(shè)置成窗口的樣式。
<activity>中配置:android :theme="@android:style/Theme.Dialog"
AIDL的全稱是什么蛤迎?如何工作确虱?能處理哪些類型的數(shù)據(jù)?
全稱是:Android Interface Define Language
AIDL(AndRoid接口描述語言)是一種接口描述語言; 編譯器可以通過aidl文件生成一段代碼替裆,通過預(yù)先定義的接口達(dá)到兩個(gè)進(jìn)程內(nèi)部通信進(jìn)程的目的. 如果需要在一個(gè)Activity中, 訪問另一個(gè)Service中的某個(gè)對象, 需要先將對象轉(zhuǎn)化成AIDL可識(shí)別的參數(shù)(可能是多個(gè)參數(shù)),然后使用AIDL來傳遞這些參數(shù), 在消息的接收端, 使用這些參數(shù)組裝成自己需要的對象.
AIDL的IPC的機(jī)制是基于接口的校辩,但它是輕量級的。它使用代理類在客戶端和實(shí)現(xiàn)層間傳遞值. 如果要使用AIDL, 需要完成2件事情:
1. 引入AIDL的相關(guān)類.;
2.調(diào)用aidl產(chǎn)生的class.
AIDL的創(chuàng)建方法:
AIDL語法很簡單,可以用來聲明一個(gè)帶一個(gè)或多個(gè)方法的接口辆童,也可以傳遞參數(shù)和返回值宜咒。 由于遠(yuǎn)程調(diào)用的需要, 這些參數(shù)和返回值并不是任何類型.下面是些AIDL支持的數(shù)據(jù)類型:
不需要import聲明的簡單Java編程語言類型(int,boolean等)
String, CharSequence不需要特殊聲明
List, Map和Parcelables類型, 這些類型內(nèi)所包含的數(shù)據(jù)成員也只能是簡單數(shù)據(jù)類型, String等其他比支持的類型.
解釋下Android程序運(yùn)行時(shí)權(quán)限與文件系統(tǒng)權(quán)限的區(qū)別。
運(yùn)行時(shí)權(quán)限D(zhuǎn)alvik(android授權(quán))
文件系統(tǒng) linux 內(nèi)核授權(quán)
系統(tǒng)上安裝了多種瀏覽器把鉴,能否指定某瀏覽器訪問指定頁面故黑?請說明原由。
通過直接發(fā)送Uri把參數(shù)帶過去,或者通過manifest里的intentfilter里的data屬性
android系統(tǒng)的優(yōu)勢和不足
5大優(yōu)勢
- 開放性
- 掙脫運(yùn)營商的束縛
- 豐富的硬件選擇
- 不受限制的開發(fā)商
- 無縫結(jié)合的Google應(yīng)用
5大不足
- 安全和隱私
- 首先開賣Android的不是最大的運(yùn)營商
- 運(yùn)營商仍然能夠影響到Android手機(jī)
- 同類機(jī)型用戶減少
- 過分依賴開發(fā)商 缺少標(biāo)準(zhǔn)配置
Android dvm的進(jìn)程和Linux的進(jìn)程, 應(yīng)用程序的進(jìn)程是否為同一個(gè)概念
DVM指Dalvik的虛擬機(jī)场晶。每一個(gè)Android應(yīng)用程序都在它自己的進(jìn)程中運(yùn)行混埠,都擁有一個(gè)獨(dú)立的Dalvik虛擬機(jī)實(shí)例。而每一個(gè)DVM都是在Linux 中的一個(gè)進(jìn)程诗轻,所以說可以認(rèn)為是同一個(gè)概念岔冀。
一條最長的短信息約占多少byte?
文70(包括標(biāo)點(diǎn)),英文160概耻,160個(gè)字節(jié)。
有一個(gè)一維整型數(shù)組int[]data保存的是一張寬為width罐呼,高為height的圖片像素值信息鞠柄。請寫一個(gè)算法,將該圖片所有的白色不透明(0xffffffff)像素點(diǎn)的透明度調(diào)整為50%
final int size = data.length;
for(int i = 0; i< size; i++){
if(data[i] == 0xffffffff)
data[i] = 0x80ffffff;
}
如何將SQLite數(shù)據(jù)庫(dictionary.db文件)與apk文件一起發(fā)布
解答:可以將dictionary.db文件復(fù)制到 Android工程中的res/raw目錄中嫉柴。所有在res/raw目錄中的文件不會(huì)被壓縮厌杜,這樣可以直接提取該目錄中的文件。
復(fù)制的基本方法是使用getResources().openRawResource方法獲得res/raw目錄中資源的 InputStream對象计螺,然后將該InputStream對象中的數(shù)據(jù)寫入其他的目錄中相應(yīng)文件中夯尽。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來打開任意目錄中的SQLite數(shù)據(jù)庫文件。
談?wù)凙ndroid的IPC(進(jìn)程間通信)機(jī)制
IPC是內(nèi)部進(jìn)程通信的簡稱. Android中的IPC機(jī)制是為了讓Activity和Service之間可以隨時(shí)的進(jìn)行交互登馒,故在Android中該機(jī)制匙握,只適用于Activity和Service之間的通信,類似于遠(yuǎn)程方法調(diào)用陈轿,類似于C/S模式的訪問圈纺。通過定義AIDL接口文件來定義IPC接口。Servier端實(shí)現(xiàn)IPC接口麦射,Client端調(diào)用IPC接口本地代理蛾娶。
DDMS和TraceView的區(qū)別?
DDMS是一個(gè)程序執(zhí)行查看器,在里面可以看見線程和堆棧等信息潜秋,TraceView是程序性能分析器.
Picasso和Glide的區(qū)別
- Picasso加載了全尺寸的圖片到內(nèi)存蛔琅,然后讓GPU來實(shí)時(shí)重繪大小。而Glide加載的大小和ImageView的大小是一致的峻呛,因此更小罗售。當(dāng)然,Picasso也可以指定加載的圖片大小的:
- Picasso和Glide在磁盤緩存策略上有很大的不同钩述。Picasso緩存的是全尺寸的莽囤,而Glide緩存的是跟ImageView尺寸相同的。
IMEI的獲取
權(quán)限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
核心代碼:
Imei = ((TelephonyManager) getSystemService(TELEPHONY_SERVICE))
.getDeviceId();
Android的性能優(yōu)化
內(nèi)存
1). 減少占用
2). 復(fù)用: 視圖的復(fù)用, 對象的復(fù)用速度
1). 網(wǎng)絡(luò)
2). 多線程響應(yīng)時(shí)間
1). 緩存: 增加內(nèi)存, 提升訪問速度;
2). 顯示加載進(jìn)度
3). 啟動(dòng)頁預(yù)加載一部分內(nèi)容
Android項(xiàng)目工程的assets目錄和raw目錄的作用
共同點(diǎn):
它們會(huì)被原封不動(dòng)的拷貝到APK中切距,而不會(huì)像其它資源文件那樣被編譯成二進(jìn)制的形式朽缎。
由 于raw是Resources (res)的子目錄,Android會(huì)自動(dòng)的為這目錄中的所有資源文件生成一個(gè)ID,這個(gè)ID會(huì)被存儲(chǔ)在R類當(dāng)中话肖,作為一個(gè)文件的引用北秽。這意味著這個(gè)資源 文件可以很容易的被Android的類和方法訪問到,甚至在Android XML文件中你也可以@raw/的形式引用到它最筒。在Android中贺氓,使用ID是訪問一個(gè)文件最快捷的方式。MP3和Ogg文件放在這個(gè)目錄下是比較合適 的床蜘。
assets目錄更像一個(gè)附錄類型的目錄辙培,Android不會(huì)為這個(gè)目錄中的文件生成ID并保存在R類當(dāng)中,因此它與 Android中的一些類和方法兼容度更低邢锯。同時(shí)扬蕊,由于你需要一個(gè)字符串路徑來獲取這個(gè)目錄下的文件描述符,訪問的速度會(huì)更慢丹擎。但是把一些文件放在這個(gè)目 錄下會(huì)使一些操作更加方便尾抑,比方說拷貝一個(gè)數(shù)據(jù)庫文件到系統(tǒng)內(nèi)存中。要注意的是蒂培,你無法在Android XML文件中引用到assets目錄下的文件再愈,只能通過AssetManager來訪問這些文件。數(shù)據(jù)庫文件和游戲數(shù)據(jù)等放在這個(gè)目錄下是比較合適的护戳。
接口和抽象類的區(qū)別
一個(gè)類只能繼承一個(gè)類(抽象類)(正如人不可能同時(shí)是生物和非生物)翎冲,但是可以實(shí)現(xiàn)多個(gè)接口(吃飯接口、走路接口)媳荒。
第一點(diǎn). 接口是抽象類的變體府适,接口中所有的方法都是抽象的。而抽象類是聲明方法的存在而不去實(shí)現(xiàn)它的類肺樟。
第二點(diǎn). 接口可以多實(shí)現(xiàn)檐春,抽象類不行
第三點(diǎn). 接口定義方法,不能實(shí)現(xiàn)么伯,而抽象類可以實(shí)現(xiàn)部分方法疟暖。
第四點(diǎn). 接口中基本數(shù)據(jù)類型為static 而抽類象不是的。
一個(gè)線程安全的Singleton, 雙重加鎖
public class Singleton{
private static Singleton instance = null;//是否是final的不重要田柔,因?yàn)樽疃嘀豢赡軐?shí)例化一次俐巴。
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
//雙重檢查加鎖,只有在第一次實(shí)例化時(shí)硬爆,才啟用同步機(jī)制欣舵,提高了性能。
synchronized(Singleton.Class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
怎樣寫一個(gè)可以更新UI的Handler
private class MyThread extends Thread{
public void run() {
// 可以更新UI的handler
Handler handler = new Hanlder(Looper.getMainLooper());
}
}
RecyclerView和ListView的區(qū)別
內(nèi)容稍多, 請大家移步到: http://www.tuicool.com/articles/aeeaQ3J
參考文章:
http://www.cnblogs.com/colife/p/5480068.html
http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html
http://www.cnblogs.com/dolphinX/p/3460545.html