0.Android手機(jī)操作系統(tǒng)的四層架構(gòu)?
Applications , Application Framework , Android RunTime Libraries , Liunx Kernel
架構(gòu)框架以此從上到下:
- Applications(應(yīng)用程序(應(yīng)用層)) Android會(huì)同一系列核心應(yīng)用程序包一起發(fā)布,該應(yīng)用程序包包括 email客戶(hù)端,SMS短消息程序,日歷,地圖,瀏覽器,聯(lián)系人管理程序等.所有的應(yīng)用程序都是使用 JAVA 語(yǔ)言編寫(xiě)的.
-
Application FrameWork(應(yīng)用程序擴(kuò)展層(框架)) 由于 Android 的手機(jī)操作系統(tǒng)是基于Liunx 2.6 系統(tǒng)之上封裝而成.所以開(kāi)發(fā)人員可也以直接訪問(wèn)核心程序所使用的API框架,該核心應(yīng)用程序的API 框架設(shè)計(jì)簡(jiǎn)化了組件的重用, 任何一個(gè)核心應(yīng)用程序(模塊)都暴露出它的功能作用,并且其他應(yīng)用程序也都可以使用該核心應(yīng)用程序(模塊)的功能(不過(guò)的遵守該核心應(yīng)用程序框架的安全性限制).同樣,該應(yīng)用 程序的重用機(jī)制也使用戶(hù)方便使用應(yīng)程序的相關(guān)組件.
API 框架隱藏的核心應(yīng)用程序是一系列的應(yīng)用程序的服務(wù)和系統(tǒng)應(yīng)用,其中包括如下:
(Android 手機(jī)中的View 是最基本的一個(gè) UI 類(lèi))
豐富而又可擴(kuò)展的視圖(手機(jī)界面所顯示的組件(Activity 上所顯示的))組件,可以用
來(lái)構(gòu)建應(yīng)用程序 如:(視圖)Views, 網(wǎng)格(grids), 文本框(text boxes), 按鈕(button), 放
置圖片區(qū)(imageview),文本編輯區(qū) (edittext), 文本顯示區(qū)(textview )等等
- Android RunTime Libraries (Android 系統(tǒng)運(yùn)行庫(kù));
- Liunx Kernel (Android 系統(tǒng)最底層核心系統(tǒng) Liunx)
1.進(jìn)程和線程什么關(guān)系?(面試中很常見(jiàn)的面試題之一)
答:每個(gè)應(yīng)用程序都有一個(gè)進(jìn)程,進(jìn)程用來(lái)處理各種各樣的任務(wù)的.一個(gè)進(jìn)程中至少有一個(gè)線程,如果任務(wù)多了,一個(gè)進(jìn)程可以有多個(gè)線程,多個(gè)線程同步進(jìn)行工作,即同步處理各種任務(wù).進(jìn)程的內(nèi)存空間,對(duì)于線程來(lái)說(shuō)是共享的 他們共享這些資源.
打個(gè)比喻 : 將應(yīng)用程序看成是公司的老板,他要去找一個(gè)懂安卓開(kāi)發(fā)的人,他把這個(gè)任務(wù)交給他的秘書(shū)去做,他的秘書(shū)相當(dāng)于一個(gè)進(jìn)程,因?yàn)槔习宥紩?huì)有秘書(shū)嘛,然后秘書(shū)覺(jué)得找一個(gè)懂安卓的人很難,然后他就將這個(gè)任務(wù)交給人事部或研發(fā)部的人去找,這些個(gè)人事部或研發(fā)部的人相當(dāng)于一個(gè)線程,那么找一個(gè)懂安卓開(kāi)發(fā)的人就很容易了.
那線程呢祭阀?
面試官why are you so diao汁汗?讓我喘口氣啊倒是
"線程間通信這個(gè)吧就是消息傳遞機(jī)制MessageQueue 啊 Loop 啊 Handler 啊 "
handler 處理收到的消息和發(fā)送的消息 消息隊(duì)列就是MessageQueue 每個(gè)線程都有一個(gè)Looper 用來(lái)讀取MessageQueue中的消息
2.CPU
這貨是計(jì)算機(jī)的核心,他會(huì)算數(shù)(承載計(jì)算任務(wù))
但是它也是普通人 一次只能運(yùn)行一個(gè)東東
進(jìn)程--->這貨就是CPU一次只能運(yùn)行一個(gè)的那個(gè)東東
一個(gè)進(jìn)程運(yùn)行的時(shí)候 其他進(jìn)程處于非運(yùn)行狀態(tài)
線程--->一個(gè)進(jìn)程可以有很多線程 他們協(xié)同完成一個(gè)任務(wù)
進(jìn)程的內(nèi)存空間 對(duì)于線程來(lái)說(shuō)是共享的 他們共享這些資源
但是某些共享是有條件的 有的只讓一個(gè)線程用 有的讓幾個(gè)線程用 其他人想用 需要給哥等著
防止等著的人插隊(duì)怎么辦 那就要加上一層鎖 比如一個(gè)房間 進(jìn)去一個(gè)線程 鎖上門(mén) 防止別人進(jìn)入 讓他們?cè)谕饷媾抨?duì) 給哥等著
這個(gè)鎖叫互斥鎖 防止多個(gè)線程同時(shí)寫(xiě)一塊內(nèi)存
還有的讓幾個(gè)人用 那怎么辦呢 就在門(mén)口放幾把鑰匙 進(jìn)去的人拿一把 鎖上門(mén) 直到門(mén)口鑰匙木有了 就進(jìn)不去了 只能給哥等著了
這些鑰匙 叫做信號(hào)量 保證多個(gè)線程不會(huì)沖突
3.什么是ANR 如何避免它鞋拟?
ANR:Application Not Responding,五秒
在Android中,活動(dòng)管理器和窗口管理器這兩個(gè)系統(tǒng)服務(wù)負(fù)責(zé)監(jiān)視應(yīng)用程序的響應(yīng)嗦篱。當(dāng)出現(xiàn)下列情況時(shí),Android就會(huì)顯示ANR對(duì)話框了:
- 對(duì)輸入事件(如按鍵幌缝、觸摸屏事件)的響應(yīng)超過(guò)5秒
- 意向接受器(intentReceiver)超過(guò)10秒鐘仍未執(zhí)行完畢
- Android應(yīng)用程序完全運(yùn)行在一個(gè)獨(dú)立的線程中(例如main)灸促。這就意味著,任何在主線程中運(yùn)行的,需要消耗大量時(shí)間的操作都會(huì)引發(fā)ANR腿宰。因?yàn)榇藭r(shí)呕诉,你的應(yīng)用程序已經(jīng)沒(méi)有機(jī)會(huì)去響應(yīng)輸入事件和意向廣播(Intent broadcast). 因此,任何運(yùn)行在主線程中的方法吃度,都要盡可能的只做少量的工作甩挫。特別是活動(dòng)生命周期中的重要方法如onCreate()和 onResume()等更應(yīng)如此。潛在的比較耗時(shí)的操作椿每,如訪問(wèn)網(wǎng)絡(luò)和數(shù)據(jù)庫(kù)伊者;或者是開(kāi)銷(xiāo)很大的計(jì)算,比如改變位圖的大小间护,需要在一個(gè)單獨(dú)的子線程中完成 (或者是使用異步請(qǐng)求亦渗,如數(shù)據(jù)庫(kù)操作)。但這并不意味著你的主線程需要進(jìn)入阻塞狀態(tài)已等待子線程結(jié)束 -- 也不需要調(diào)用Therad.wait()或者Thread.sleep()方法汁尺。取而代之的是法精,主線程為子線程提供一個(gè)句柄(Handler),讓子線程 在即將結(jié)束的時(shí)候調(diào)用它痴突。使用這種方法涉及你的應(yīng)用程序搂蜓,能夠保證你的程序?qū)斎氡3至己玫捻憫?yīng),從而避免因?yàn)檩斎胧录^(guò)5秒鐘不被處理而產(chǎn)生的ANR辽装。這種實(shí)踐需要應(yīng)用到所有顯示用戶(hù)界面的線程帮碰,因?yàn)樗麄兌济媾R著同樣的超時(shí)問(wèn)題。
簡(jiǎn)單回答:
在Android上拾积,如果你的應(yīng)用程序有一段時(shí)間響應(yīng)不夠靈敏殉挽,系統(tǒng)會(huì)向用戶(hù)顯示一個(gè)對(duì)話框,這個(gè)對(duì)話框稱(chēng)作應(yīng)用程序無(wú)響應(yīng)(ANR:Application Not Responding)對(duì)話框拓巧。用戶(hù)可以選擇讓程序繼續(xù)運(yùn)行斯碌,但是,他們?cè)谑褂媚愕膽?yīng)用程序時(shí)玲销,并不希望每次都要處理這個(gè)對(duì)話框输拇。因此,在程序里對(duì)響應(yīng)性能的設(shè)計(jì)很重要贤斜,這樣策吠,系統(tǒng)不會(huì)顯示ANR給用戶(hù)。
4.簡(jiǎn)要解釋一下Activity瘩绒、 Intent 猴抹、Intent filter、Service锁荔、Broadcast蟀给、BroadcaseReceiver
一個(gè)Activity呈現(xiàn)了一個(gè)用戶(hù)可以操作的可視化用戶(hù)界面
一個(gè)Service不包含可見(jiàn)的用戶(hù)界面,而是在后臺(tái)無(wú)限地運(yùn)行,可以連接到一個(gè)正在運(yùn)行的服務(wù)中,連接后跋理,可以通過(guò)服務(wù)中暴露出來(lái)的接口與其進(jìn)行通信
一個(gè)BroadcastReceiver是一個(gè)接收廣播消息并作出回應(yīng)的component择克,broadcast receiver沒(méi)有界面
intent:content provider在接收到ContentResolver的請(qǐng)求時(shí)被激活。
activity, service和broadcast receiver是被稱(chēng)為intents的異步消息激活的前普。
一個(gè)intent是一個(gè)Intent對(duì)象肚邢,它保存了消息的內(nèi)容。對(duì)于activity和service來(lái)說(shuō)拭卿,它指定了請(qǐng)求的操作名稱(chēng)和待操作數(shù)據(jù)的URI
Intent對(duì)象可以顯式的指定一個(gè)目標(biāo)component骡湖。如果這樣的話,android會(huì)找到這個(gè)component(基于manifest文件中的聲明)并激活它峻厚。但如果一個(gè)目標(biāo)不是顯式指定的响蕴,android必須找到響應(yīng)intent的最佳component。
它是通過(guò)將Intent對(duì)象和目標(biāo)的intent filter相比較來(lái)完成這一工作的惠桃。一個(gè)component的intent filter告訴android該component能處理的intent浦夷。intent filter也是在manifest文件中聲明的。
5.什么是IntentService刽射?有何優(yōu)點(diǎn)军拟?
普通的service ,默認(rèn)運(yùn)行在ui main 主線程 , Sdk給我們提供的方便的,帶有異步處理的service類(lèi), 異步處理的方法 OnHandleIntent() 可以在此方法中處理耗時(shí)的操作.
優(yōu)點(diǎn)如下:
- Acitivity的進(jìn)程,當(dāng)處理Intent的時(shí)候誓禁,會(huì)產(chǎn)生一個(gè)對(duì)應(yīng)的Service
- Android的進(jìn)程處理器現(xiàn)在會(huì)盡可能的不kill掉你
- 非常容易使用
6.什么是Activity?
四大組件之一,一般的,一個(gè)用戶(hù)交互界面對(duì)應(yīng)一個(gè)activity, activity 是Context的子類(lèi),同時(shí)實(shí)現(xiàn)了window.callback和keyevent.callback, 可以處理與窗體用戶(hù)交互的事件. 我開(kāi)發(fā)常用的的有ListActivity , PreferenceActivity 等…如果界面有共同的特點(diǎn)或者功能的時(shí)候,還會(huì)自己定義一個(gè)BaseActivity.
7.請(qǐng)描述一下Activity生命周期。
生命周期描述的是一個(gè)類(lèi)從創(chuàng)建(new出來(lái))到死亡(垃圾回收)的過(guò)程中會(huì)執(zhí)行的方法.在這個(gè)過(guò)程中會(huì)針對(duì)不同的生命階段會(huì)調(diào)用不同的方法Activity從創(chuàng)建到銷(xiāo)毀有多種狀態(tài)肾档,從一種狀態(tài)到另一種狀態(tài)時(shí)會(huì)激發(fā)相應(yīng)的回調(diào)方法摹恰,這些回調(diào)方法包括:oncreate ondestroy onstop onstart onresume onpause 其實(shí)這些方法都是兩兩對(duì)應(yīng)的:
onCreate創(chuàng)建與onDestroy銷(xiāo)毀;
onStart可見(jiàn)與onStop不可見(jiàn)怒见;
onResume可編輯(即焦點(diǎn))與onPause俗慈;
這6個(gè)方法是相對(duì)應(yīng)的,那么就只剩下一個(gè)onRestart方法了遣耍,這個(gè)方法在什么時(shí)候調(diào)用呢闺阱?答案就是:在Activity被onStop后,但是沒(méi)有被onDestroy舵变,在再次啟動(dòng)此Activity時(shí)就調(diào)用onRestart(而不再調(diào)用onCreate)方法酣溃;如果被onDestroy了,則是調(diào)用onCreate方法纪隙。
最后講自己項(xiàng)目中的經(jīng)驗(yàn),比如說(shuō)豆瓣客戶(hù)端每次進(jìn)入某個(gè)界面的時(shí)候要刷新列表,這個(gè)刷新列表的操作 就放在onStart()的方法里面.這樣保證每次用戶(hù)看到的數(shù)據(jù)都是最新的.多媒體播放, 播放來(lái)電話. onStop() 視頻, 視頻聲音設(shè)置為0 , 記錄視頻播放的位子 onStart() 根據(jù)保存的狀態(tài)恢復(fù)現(xiàn)場(chǎng).
8.兩個(gè)Activity之間跳轉(zhuǎn)時(shí)必然會(huì)執(zhí)行的是哪幾個(gè)方法赊豌。
一般情況比如說(shuō)有兩個(gè)activity,分別叫A,B ,當(dāng)在A里面激活B組件的時(shí)候, A 會(huì)調(diào)用 onPause()方法,然后B 調(diào)用onCreate() ,onStart(), OnResume() , 這個(gè)時(shí)候B覆蓋了窗體, A會(huì)調(diào)用onStop()方法. 如果B呢 是個(gè)透明的,或者是對(duì)話框的樣式, 就不會(huì)調(diào)用onStop()方法
9.Android工程下面有個(gè)gen目錄,該目錄下有個(gè)R.java文件绵咱,該文件的作用是什么碘饼,能不能修改,為什么?
答:作用->該文件相當(dāng)于項(xiàng)目的字典,項(xiàng)目中所涉及到的用戶(hù)界面、字符串艾恼、圖片住涉、聲音等資源都會(huì)在該文件中創(chuàng)建一個(gè)唯一ID編號(hào),這些編號(hào)為整形钠绍,以16進(jìn)制自動(dòng)生成秆吵。項(xiàng)目要使用這些資源時(shí),會(huì)通過(guò)這個(gè)類(lèi)得到資源的引用五慈。因?yàn)槭窍到y(tǒng)自動(dòng)生成,所以不能夠被修改.
10.把文件名為“圖片1.jpg”的一張圖片放到android工程下的res- drawable-mdpi下纳寂,會(huì)不會(huì)報(bào)錯(cuò),為什么泻拦?
答:會(huì)報(bào)錯(cuò),因?yàn)槲募荒転閍-z,0-9和下劃線毙芜。如果名稱(chēng)合適是不會(huì)報(bào)錯(cuò)的.因?yàn)槭褂肁ndroid系統(tǒng)的手機(jī)可能采用不同的分辨率,所以在開(kāi)發(fā)的時(shí)候會(huì)要求有不同分辨率的圖片争拐,drawable-hdpi存高分辨率的,drawable-mdpi存中等分辨率的,drawable-ldpi存低分辨率的腋粥,所以,你要把相同的圖片用圖片處理軟件處理成不同的分辨率的圖片架曹,然后分別保存隘冲,當(dāng)然了,如果你嫌麻煩绑雄,也可以在三個(gè)目錄下保存相同的圖片展辞,這樣也沒(méi)有問(wèn)題,但是不符合開(kāi)發(fā)的初衷万牺。
11.Bitmap.Config下的幾個(gè)圖片質(zhì)量參數(shù)
Bitmap.Config ALPHA_8
Bitmap.Config ARGB_4444
Bitmap.Config ARGB_8888
Bitmap.Config RGB_565
簡(jiǎn)要解釋下每個(gè)參數(shù)的含義 罗珍。
A R G B
透明度 紅色 綠色 藍(lán)色
Bitmap.Config ARGB_4444 16 每個(gè)像素 占四位
Bitmap.Config ARGB_8888 32 每個(gè)像素 占八位
Bitmap.Config RGB_565 16 R占5位 G占6位 B占5位 沒(méi)有透明度(A)
12.res和Assets的區(qū)別?
assets和res目錄都能存放資源文件,但是與res不同的是,assets支持任意深度的子目錄脚粟,在它里面的文件不會(huì)在R.java里生成任何資源ID
13.setOnTouchEvent 返回值為true 和 false有何區(qū)別覆旱?
返回true表示這個(gè)消息已經(jīng)被處理結(jié)束,后續(xù)的handler不再接收到這個(gè)消息
Return true if you have consumed the event, false if you haven't.
The default implementation always returns false.
14.闡述android:padding和android:layout_margin的異同核无?
(1)不同點(diǎn):android:padding 是站在父View 的角度描述問(wèn)題扣唱,它規(guī)定它里面的內(nèi)容必須與這個(gè)父View 邊界的距離。android:layout_margin 則是站在自己角度描述問(wèn)題团南,規(guī)定自己和其他(上下左右)的 View 之間的距離 , 如果一級(jí)只有一個(gè)View噪沙,那么他的效果基本上就和padding一樣。
(2)相同點(diǎn):如同一級(jí)只有一個(gè)View已慢,那么android:layout_margin的效果基本上就和android:padding一樣
15.關(guān)于ContenValues類(lèi)說(shuō)法
他和Hashtable比較類(lèi)似曲聂,也是負(fù)責(zé)存儲(chǔ)一些名值對(duì),但是他存儲(chǔ)的名值對(duì)當(dāng)中的名是String類(lèi)型佑惠,而值都是基本類(lèi)型
16.關(guān)于Android dvm的進(jìn)程和Linux的進(jìn)程,應(yīng)用程序的進(jìn)程否為同一個(gè)概念?
DVM指dalivk的虛擬機(jī).每一個(gè)Android應(yīng)用程序都在它自己的進(jìn)程中運(yùn)行,都擁有一個(gè)獨(dú)立的Dalvik虛擬機(jī)實(shí)例.而每一個(gè)DVM都是在Linux 中的一個(gè)進(jìn)程,所以說(shuō)可以認(rèn)為是同一個(gè)概念.
17.Android項(xiàng)目工程下面的assets目錄的作用是什么?
主要放置多媒體等數(shù)據(jù)文件
18.關(guān)于res/raw目錄
這里的文件是原封不動(dòng)的存儲(chǔ)到設(shè)備上不會(huì)轉(zhuǎn)換為二進(jìn)制的格式
19.對(duì)android NDK的理解
- NDK是一系列工具的集合
- NDK 提供了一份穩(wěn)定朋腋、功能有限的 API 頭文件聲明齐疙。
- 使 “Java+C” 的開(kāi)發(fā)方式終于轉(zhuǎn)正,成為官方支持的開(kāi)發(fā)方式
- NDK 將是 Android 平臺(tái)支持 C 開(kāi)發(fā)的開(kāi)端
20.在android中旭咽,請(qǐng)簡(jiǎn)述jni的調(diào)用過(guò)程
- 安裝和下載Cygwin贞奋,下載 Android NDK
- 在ndk項(xiàng)目中JNI接口的設(shè)計(jì)
- 使用C/C++實(shí)現(xiàn)本地方法
- JNI生成動(dòng)態(tài)鏈接庫(kù).so文件
- 將動(dòng)態(tài)鏈接庫(kù)復(fù)制到j(luò)ava工程,在java工程中調(diào)用穷绵,運(yùn)行java工程即可
21.handler機(jī)制的原理
andriod提供了Handler和Looper來(lái)滿(mǎn)足線程間的通信轿塔。Handler先進(jìn)先出原則。Looper類(lèi)用來(lái)管理特定線程內(nèi)對(duì)象之間的消息交換(Message Exchange)仲墨。
- Looper: 一個(gè)線程可以產(chǎn)生一個(gè)Looper對(duì)象勾缭,由它來(lái)管理此線程里的Message Queue(消息隊(duì)列)。
- Handler: 你可以構(gòu)造Handler對(duì)象來(lái)與Looper溝通目养,以便push新消息到Message Queue里;或者接收Looper從Message Queue取出所送來(lái)的消息俩由。
- Message Queue(消息隊(duì)列):用來(lái)存放線程放入的消息。
- 線程:UI thread 通常就是main thread癌蚁,而Android啟動(dòng)程序時(shí)會(huì)替它建立一個(gè)Message Queue幻梯。
22.說(shuō)說(shuō)mvc模式的原理以及它在android中的運(yùn)用
android的官方建議應(yīng)用程序的開(kāi)發(fā)采用mvc模式。何謂mvc努释?mvc是model,view,controller的縮寫(xiě)碘梢,mvc包含三個(gè)部分:
- 模型(model)對(duì)象:是應(yīng)用程序的主體部分,所有的業(yè)務(wù)邏輯都應(yīng)該寫(xiě)在該層伐蒂。
- 視圖(view)對(duì)象:是應(yīng)用程序中負(fù)責(zé)生成用戶(hù)界面的部分煞躬。也是在整個(gè)mvc架構(gòu)中用戶(hù)唯一可以看到的一層,接收用戶(hù)的輸入饿自,顯示處理結(jié)果汰翠。
- 控制器(control)對(duì)象:是根據(jù)用戶(hù)的輸入,控制用戶(hù)界面數(shù)據(jù)顯示及更新model對(duì)象狀態(tài)的部分昭雌,控制器更重要的一種導(dǎo)航功能,想用用戶(hù)出發(fā)的相關(guān)事件健田,交給m哦得了處理烛卧。
android鼓勵(lì)弱耦合和組件的重用,在android中mvc的具體體現(xiàn)如下:
- 視圖層(view):一般采用xml文件進(jìn)行界面的描述妓局,使用的時(shí)候可以非常方便的引入总放,當(dāng)然,如何你對(duì)android了解的比較的多了話好爬,就一定可以想到在android中也可以使用javascript+html等的方式作為view層局雄,當(dāng)然這里需要進(jìn)行java和javascript之間的通信,幸運(yùn)的是存炮,android提供了它們之間非常方便的通信實(shí)現(xiàn)炬搭。
- 控制層(controller):android的控制層的重任通常落在了眾多的acitvity的肩上蜈漓,這句話也就暗含了不要在acitivity中寫(xiě)代碼,要通過(guò)activity交割model業(yè)務(wù)邏輯層處理宫盔,這樣做的另外一個(gè)原因是android中的acitivity的響應(yīng)時(shí)間是5s融虽,如果耗時(shí)的操作放在這里,程序就很容易被回收掉灼芭。
- 模型層(model):對(duì)數(shù)據(jù)庫(kù)的操作有额、對(duì)網(wǎng)絡(luò)等的操作都應(yīng)該在model里面處理,當(dāng)然對(duì)業(yè)務(wù)計(jì)算等操作也是必須放在的該層的彼绷。
23.請(qǐng)介紹下Android的數(shù)據(jù)存儲(chǔ)方式巍佑。
Android提供了5種方式存儲(chǔ)數(shù)據(jù):
- 使用SharedPreferences存儲(chǔ)數(shù)據(jù);位置 :
/data/data/包名/shared_preps
- 文件存儲(chǔ)數(shù)據(jù)寄悯; 需要訪問(wèn)權(quán)限,位置 :
/data/data/包名/files
- SQLite數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù)萤衰;
- 使用ContentProvider存儲(chǔ)數(shù)據(jù);
- 網(wǎng)絡(luò)存儲(chǔ)數(shù)據(jù)热某;
Android 中的數(shù)據(jù)存儲(chǔ)都是私有的腻菇,其他應(yīng)用程序都是無(wú)法訪問(wèn)的,除非通過(guò)ContentResolver獲取其他程序共享的數(shù)據(jù)昔馋。
24.請(qǐng)介紹下ContentProvider是如何實(shí)現(xiàn)數(shù)據(jù)共享的筹吐。
一個(gè)程序可以通過(guò)實(shí)現(xiàn)一個(gè)Content provider的抽象接口將自己的數(shù)據(jù)完全暴露出去,而且Content providers是以類(lèi)似數(shù)據(jù)庫(kù)中表的方式將數(shù)據(jù)暴露秘遏。Content providers存儲(chǔ)和檢索數(shù)據(jù)丘薛,通過(guò)它可以讓所有的應(yīng)用程序訪問(wèn)到,這也是應(yīng)用程序之間唯一共享數(shù)據(jù)的方法邦危。要想使應(yīng)用程序的數(shù)據(jù)公開(kāi)化洋侨,可通過(guò)2種方法:創(chuàng)建一個(gè)屬于你自己的Content provider或者將你的數(shù)據(jù)添加到一個(gè)已經(jīng)存在的Content provider中,前提是有相同數(shù)據(jù)類(lèi)型并且有寫(xiě)入Content provider的權(quán)限倦蚪。
如何通過(guò)一套標(biāo)準(zhǔn)及統(tǒng)一的接口獲取其他應(yīng)用程序暴露的數(shù)據(jù)希坚?Android提供了ContentResolver,外界的程序可以通過(guò)ContentResolver接口訪問(wèn)ContentProvider提供的數(shù)據(jù)陵且。
25.SIM卡的EF文件有何作用?
SIM卡的文件系統(tǒng)有自己規(guī)范,主要是為了和手機(jī)通訊,SIM卡本身可以有自己的操作系統(tǒng),EF就是作存儲(chǔ)并和手機(jī)通訊用的.
26.一條最長(zhǎng)的短信息約占多少byte?
中文70(包括標(biāo)點(diǎn)),英文160裁僧,160個(gè)字節(jié),這個(gè)說(shuō)法不準(zhǔn)確,跟手機(jī)制式,運(yùn)營(yíng)商等信息有關(guān).
做實(shí)驗(yàn),看源碼
ArrayList<String> msgs = sms.divideMessage(message);
for (String msg : msgs) {
sms.sendTextMessage(phoneNumber, null, msg, pi, null);
}
27.Android中的動(dòng)畫(huà)有哪幾類(lèi),它們的特點(diǎn)和區(qū)別是什么?
兩種. 一種是Tween動(dòng)畫(huà).還有一種是Frame動(dòng)畫(huà).
- Tween動(dòng)畫(huà),這種實(shí)現(xiàn)方式可以使視圖組件移動(dòng).放大.縮小以及產(chǎn)生透明度的變化;
- 控制View的動(dòng)畫(huà)
- alpha(AlphaAnimation) 漸變透明
- scale(ScaleAnimation) 漸變尺寸伸縮
- translate(TranslateAnimation)畫(huà)面轉(zhuǎn)換、位置移動(dòng)
- rotate(RotateAnimation)畫(huà)面轉(zhuǎn)移慕购,旋轉(zhuǎn)動(dòng)畫(huà)
- 控制一個(gè)Layout里面子View的動(dòng)畫(huà)效果
- layoutAnimation(LayoutAnimationController)
- grid Animation(GridLayoutAnimationController)
- 控制View的動(dòng)畫(huà)
- Frame動(dòng)畫(huà),傳統(tǒng)的動(dòng)畫(huà)方法,通過(guò)順序的播放排列好的圖片來(lái)實(shí)現(xiàn),類(lèi)似電影.
28.什么是嵌入式實(shí)時(shí)操作系統(tǒng),Android 操作系統(tǒng)屬于實(shí)時(shí)操作系統(tǒng)嗎?
嵌入式實(shí)時(shí)操作系統(tǒng)是指當(dāng)外界事件或數(shù)據(jù)產(chǎn)生時(shí),能夠接受并以足夠快的速度予以處理,其處理的結(jié)果又能在規(guī)定的時(shí)間之內(nèi)來(lái)控制生產(chǎn)過(guò)程或?qū)μ幚硐到y(tǒng)作出快速響應(yīng),并控制所有實(shí)時(shí)任務(wù)協(xié)調(diào)一致運(yùn)行的嵌入式操作系統(tǒng).
主要用于工業(yè)控制,軍事設(shè)備,航空航天等領(lǐng)域?qū)ο到y(tǒng)的響應(yīng)時(shí)間有苛刻的要求,這就需要使用實(shí)時(shí)系統(tǒng).又可分為軟實(shí)時(shí)和硬實(shí)時(shí)兩種,而Android是基于linux內(nèi)核的,因此屬于軟實(shí)時(shí).
29.ArrayList和Vector的區(qū)別
- Vector是線程安全的,ArrayList是線程不安全的
- ArrayList效率更高,Vector速度慢
- 當(dāng)需要增加空間大小的時(shí)候聊疲,ArrayList增加原來(lái)的一半,Vector增加原來(lái)的一倍沪悲。
30.TCP和UDP的區(qū)別获洲?
31.實(shí)現(xiàn)多線程的方式和區(qū)別隘竭?
32.排序算法有哪些帆精?編寫(xiě)任意一個(gè)排序算法的程序君仆。
33.寫(xiě)出listview中一些常用的優(yōu)化
如果一個(gè)listView不做任何的優(yōu)化,而且有很多的條目,當(dāng)我們快速的拖動(dòng)listView的界面的時(shí)候,就不斷的GCGC(Garbage Collection )垃圾回收,當(dāng)GC到某個(gè)時(shí)候就會(huì)(OOM)outofmemory內(nèi)存溢出铃岔,應(yīng)用程序也就會(huì)隨之掛掉,產(chǎn)生這個(gè)問(wèn)題的原因是什么呢飞崖?我們知道listView的特點(diǎn)是每產(chǎn)生一個(gè)條目就會(huì)調(diào)用一次getView方法烂叔,如果我們不進(jìn)行優(yōu)化,每一次調(diào)用都要執(zhí)行g(shù)etView方法中的所有語(yǔ)句固歪,而且會(huì)在最上面的條目移出界面的時(shí)候回收掉這個(gè)對(duì)象蒜鸡,這樣是比較浪費(fèi)資源的。
這時(shí)候我們就會(huì)想牢裳,如果在條目移出界面的時(shí)候不對(duì)它進(jìn)行回收逢防,而是拿回來(lái)再次使用,這樣不就優(yōu)化了ListView的效率了嗎蒲讯?幸好忘朝,一向給力的谷歌工程師為我們提供了ListView自身的緩存機(jī)制,它會(huì)緩存條目中的一個(gè)條目判帮,當(dāng)界面最上方的這個(gè)條目顯示完成之后局嘁,就會(huì)出現(xiàn)一個(gè)緩存條目,也就是BaseView中g(shù)etView方法中的convertView 晦墙,convertView的作用其實(shí)就是一個(gè)已經(jīng)被系統(tǒng)回收的歷史緩存View對(duì)象悦昵,我們可以利用這個(gè)對(duì)象就沒(méi)有必要再重新去xml文件中去解析布局了。判斷傳進(jìn)來(lái)的參數(shù)convertView是否為null晌畅,如果為null就創(chuàng)建convertView并返回但指,如果不為null,則直接使用抗楔。
這是第一種優(yōu)化方法棋凳,簡(jiǎn)單的說(shuō)就是復(fù)用歷史緩存的View對(duì)象,減少view對(duì)象創(chuàng)建的次數(shù)连躏。
第二種優(yōu)化方法是減少findViewById()的次數(shù)剩岳,findViewById是一個(gè)相對(duì)比較耗性能的操作,因?yàn)槊看卧趃etVIew的時(shí)候入热,都需要重新的findViewById卢肃,重新找到控件,然后進(jìn)行控件的賦值以及事件相應(yīng)設(shè)置才顿。這樣其實(shí)在做重復(fù)的事情,因?yàn)榈膅etView中尤蒿,其實(shí)包含有這些控件郑气,而且這些控件的id還都是一樣的,也就是其實(shí)只要在view中findViewById一次腰池,后面無(wú)需要每次都要findViewById了尾组。解決這個(gè)問(wèn)題的方法就是把item里面的控件封裝成一個(gè)javaBean忙芒,當(dāng)item條目被加載的時(shí)候就去找到對(duì)應(yīng)的控件 。
前兩種優(yōu)化方式是最一般的優(yōu)化讳侨,一般我們使用listView的時(shí)候都會(huì)用到這兩個(gè)優(yōu)化方法呵萨,但是只有這兩種方式還遠(yuǎn)遠(yuǎn)不夠,比如當(dāng)listView的View對(duì)象中有圖片資源的時(shí)候跨跨,就會(huì)占用大量的內(nèi)存潮峦,這樣就很容易造成內(nèi)存溢出,對(duì)于這種情況有兩種優(yōu)化方法勇婴,
分批加載和分頁(yè)加載忱嘹,
我把這兩種方法看成是利用時(shí)間不同的優(yōu)化和利用空間的不同的優(yōu)化。分批加載耕渴,我們每次只加載一定數(shù)量拘悦,就像是在不同的時(shí)間段加載一次。而分頁(yè)加載橱脸,就像是把一定數(shù)量的條目放在不同的空間础米,利用這兩種思想來(lái)實(shí)現(xiàn)分批加載和分頁(yè)加載。
分批加載主要解決的是用戶(hù)體驗(yàn)的問(wèn)題添诉,如果數(shù)據(jù)量過(guò)大屁桑,用戶(hù)等待的時(shí)間就會(huì)很長(zhǎng),而且也會(huì)出現(xiàn)Anr異常吻商。比如我們要從數(shù)據(jù)庫(kù)中讀取100條數(shù)據(jù)掏颊,如果一次性讀取,就需要很長(zhǎng)的時(shí)間艾帐,但是這時(shí)我們修改sql語(yǔ)句乌叶,指定從那一條開(kāi)始獲取數(shù)據(jù),一共獲取多少數(shù)據(jù)柒爸,sql語(yǔ)句是:
"selectphone,mode from blacknumber limit ? Offset ?"准浴,new String[]{String.valueOfa(maxNumber),String.valueOf(StateIndex)}
新獲取的數(shù)據(jù)加到集合的末尾即可。
說(shuō)分頁(yè)加載捎稚,它的實(shí)現(xiàn)思路是這樣的乐横,實(shí)現(xiàn)OnScrollListener接口,重寫(xiě)onScrollStateChanged和onScroll方法今野,使用onScroll方法實(shí)現(xiàn)“滑動(dòng)”后處理檢查是否還有新紀(jì)錄葡公,如果有,調(diào)用addFooterView条霜,添加記錄到adapter催什,adapter調(diào)用notifyDataSetChanged更新數(shù)據(jù);如果沒(méi)有新紀(jì)錄了宰睡,把自定義的mFooterView去掉蒲凶,使用onScrollStateChanged可以檢測(cè)是否滾到最后一行且停止?jié)L到然后執(zhí)行加載气筋。
還有一種優(yōu)化方式是利用圖片異步加載的方法,實(shí)現(xiàn)思路是:
1.先從內(nèi)存緩存中獲取圖片顯示(內(nèi)存緩沖)
2.獲取不到的話從SD卡里獲刃病(SD卡緩沖宠默,從SD卡獲取圖片是放在子線程里執(zhí)行的,否則快速劃瓶的話會(huì)不夠流暢)
3.都獲取不到的話從網(wǎng)絡(luò)下載圖片并保存到SD卡同時(shí)加入內(nèi)存并顯示(視情況看是否要顯示)
我們?cè)谑褂胠istview的時(shí)候可能會(huì)出現(xiàn)圖片亂跳(錯(cuò)位)的問(wèn)題:
圖片錯(cuò)位問(wèn)題的本質(zhì)源于我們的listview使用了緩存convertView灵巧,假設(shè)一種場(chǎng)景搀矫,一個(gè)listview一屏顯示九個(gè)item,那么在拉出第十個(gè)item的時(shí)候孩等,事實(shí)上該item是重復(fù)使用了第一個(gè)item艾君,也就是說(shuō)在第一個(gè)item從網(wǎng)絡(luò)中下載圖片并最終要顯示的時(shí)候,其實(shí)該item已經(jīng)不在當(dāng)前顯示區(qū)域內(nèi)了肄方,此時(shí)顯示的后果將可能在第十個(gè)item上輸出圖像冰垄,這就導(dǎo)致了圖片錯(cuò)位的問(wèn)題。所以解決之道在于可見(jiàn)則顯示权她,不可見(jiàn)則不顯示虹茶。在ImageLoader里有個(gè)imageViews的map對(duì)象,就是用于保存當(dāng)前顯示區(qū)域圖像對(duì)應(yīng)的url集隅要,在顯示前判斷處理一下即可蝴罪。
34.“==”和equals方法有什么區(qū)別?
“==”操作符專(zhuān)門(mén)用來(lái)比較兩個(gè)變量的值是否相等步清,也就是用于比較變量所對(duì)應(yīng)的內(nèi)存中所存儲(chǔ)的數(shù)值是否相同要门。equals方法用于比較兩個(gè)獨(dú)立對(duì)象的內(nèi)容是否相同。比如廓啊,要比較一個(gè)字符串對(duì)象的引用對(duì)象變量的地址值是否相同欢搜,就用"==",而要比較字符串對(duì)象中的內(nèi)容是否相同,則用equals方法谴轮。
35.靜態(tài)變量和實(shí)例變量的區(qū)別炒瘟?
靜態(tài)變量屬于類(lèi),也稱(chēng)為類(lèi)變量第步,它可以通過(guò)類(lèi)名直接調(diào)用使用疮装。
實(shí)例變量屬于某個(gè)對(duì)象的屬性,必須創(chuàng)建了實(shí)例對(duì)象粘都,才能使用實(shí)例對(duì)象去調(diào)用實(shí)例變量廓推。
36.Integer與int的區(qū)別?
- int是java提供的8種基本數(shù)據(jù)類(lèi)型之一翩隧。
- Integer是java為int提供的封裝類(lèi)受啥。
- int的默認(rèn)值為0,而Integer的默認(rèn)值為null.
37.OverLoad(重載)和Override(重寫(xiě))的區(qū)別?
- 重載表示同一個(gè)類(lèi)中可以有多個(gè)名稱(chēng)相同的方法滚局,但這些方法的參數(shù)列表各不相同。
- 重寫(xiě)表示子類(lèi)中的方法可以與父類(lèi)中的某個(gè)方法的名稱(chēng)和參數(shù)完全相同顽频。
38.抽象類(lèi)與接口的區(qū)別藤肢?
- 抽象類(lèi)可以有構(gòu)造方法,接口中不能有構(gòu)造方法糯景。
- 抽象類(lèi)中可以有普通成員變量嘁圈,接口中沒(méi)有普通成員變量。
- 抽象類(lèi)中可以包含非抽象方法蟀淮,接口中的所有方法必須都是抽象的最住。
- 抽象類(lèi)中可以包含靜態(tài)方法,接口中不能包含靜態(tài)方法怠惶。
- 抽象類(lèi)中的抽象方法的訪問(wèn)類(lèi)型可以是public,protected,接口中的抽象方法只能是public類(lèi)型的涨缚,并且默認(rèn)即為public abstract類(lèi)型。
39.String和StringBuffer的區(qū)別策治?
String的長(zhǎng)度是不可以改變的脓魏,StringBuffer的長(zhǎng)度是可變的。
40.final,finally,finalize的區(qū)別通惫?
- final是一個(gè)修飾符茂翔,用于修飾屬性,方法和類(lèi)履腋,分別表示屬性不可變珊燎,方法不可覆蓋,類(lèi)不可以被繼承遵湖。
- finally是異常處理語(yǔ)句結(jié)構(gòu)的一部分悔政,它里面的代碼一定會(huì)執(zhí)行。
- finalize是Object類(lèi)的一個(gè)方法奄侠,在垃圾回收器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法卓箫,可以覆蓋這個(gè)方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件垄潮。
41.運(yùn)行時(shí)異常和一般異常的異同烹卒?
異常表示程序運(yùn)行過(guò)程中可能出現(xiàn)的非正常狀態(tài)。
- 運(yùn)行時(shí)異常表示虛擬機(jī)的通常操作中可能遇到的異常弯洗,是一種常見(jiàn)運(yùn)行錯(cuò)誤旅急。
- java編譯器要求方法必須聲明拋出可能發(fā)生的非運(yùn)行時(shí)異常,但并不要求必須聲明拋出未被捕獲的運(yùn)行時(shí)異常牡整。
42.error和exception有什么區(qū)別藐吮?
- error表示恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問(wèn)題。比如內(nèi)存溢出。程序是不可能處理這樣的情況谣辞。
- exception表示一種設(shè)計(jì)或?qū)崿F(xiàn)問(wèn)題迫摔,如果程序運(yùn)行一直正常,那么exception就不會(huì)發(fā)生泥从。
43.sleep()和wait()的區(qū)別句占?
- sleep是線程類(lèi)Thread的方法,調(diào)用它時(shí)將導(dǎo)致線程暫停執(zhí)行指定的時(shí)間躯嫉,將執(zhí)行機(jī)會(huì)給其他線程纱烘,但監(jiān)控狀態(tài)依然保持,到時(shí)間后會(huì)自動(dòng)恢復(fù)祈餐。調(diào)用sleep方法不會(huì)釋放對(duì)象鎖擂啥。
- wait是Object類(lèi)的方法,調(diào)用它時(shí)將導(dǎo)致本線程放棄對(duì)象鎖帆阳,進(jìn)入等待此對(duì)象的等待鎖定池哺壶,只有針對(duì)此對(duì)象發(fā)出notify方法(或notifyAll)后,本線程才進(jìn)入對(duì)象鎖定池準(zhǔn)備獲得對(duì)象鎖進(jìn)入運(yùn)行狀態(tài)舱痘。
44.HashMap和Hashtable的區(qū)別变骡?
- HashMap是線程不安全的,Hashtable是線程安全的芭逝。
- HashMap可以接受null作為鍵和值塌碌,Hashtable不可以接受null作為鍵和值。
45.List和Map的區(qū)別旬盯?
- List是存儲(chǔ)單列數(shù)據(jù)的集合台妆,Map是存儲(chǔ)鍵和值這樣的雙列數(shù)據(jù)的集合。
- List中存儲(chǔ)的數(shù)據(jù)是有順序的胖翰,并且數(shù)據(jù)可以重復(fù)接剩。
- Map中存儲(chǔ)的數(shù)據(jù)是沒(méi)有順序的,它的鍵不能重復(fù)萨咳,值可以有重復(fù)懊缺。
46.Collection和Collections的區(qū)別?
- Collection是集合類(lèi)的上級(jí)接口培他,繼承于它的接口主要有List和Set.
- Collections是針對(duì)集合類(lèi)的一個(gè)工具類(lèi)鹃两,它里面提供了一系列的靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索,排序舀凛,線程安全化等操作俊扳。
47.堆與棧的區(qū)別?
- 棧用于存放方法內(nèi)部的局部變量猛遍。當(dāng)方法結(jié)束時(shí)馋记,分配給此方法的棧會(huì)釋放出來(lái)号坡。
- 堆用于存放用new產(chǎn)生的數(shù)據(jù)和數(shù)組。它不會(huì)隨方法的結(jié)束而消失梯醒。
48.簡(jiǎn)述synchronized和java.util.concurrent.locks.Lock的異同宽堆?
- 主要相同點(diǎn):Lock能完成synchronized所實(shí)現(xiàn)的所有功能
- 主要不同點(diǎn):Lock有比synchronized更精確的線程語(yǔ)義和更好的性能。
- synchronized會(huì)自動(dòng)釋放鎖冤馏,而Lock一定要求程序員手工釋放日麸,并且必須在finally從句中釋放。
- Lock還有更強(qiáng)大的功能逮光,例如,它的tryLock方法可以非阻塞方式去拿鎖墩划。
50.以下代碼片段輸出?
public class A{
static{
System.out.println("1") ;
}
public A(){
System.ot.println("A") ;
}
}
public class B extends A{
static{
System.out.println("2") ;
}
public B(){
System.ot.println("B") ;
}
}
問(wèn)題:
A ab = new B() ;//這里會(huì)輸出什么 1 2 a b
ab = new B() ;//這里會(huì)輸出什么 a b
原因 : 靜態(tài)代碼塊只調(diào)用一次
51.請(qǐng)寫(xiě)出冒泡排序(原理涕刚、實(shí)現(xiàn))(高級(jí)程序員)
冒泡排序:bubbleSort
原理:將數(shù)組中的元素,進(jìn)行兩兩相比較乙帮,然后將較小的數(shù)向上移就好比是水泡向上冒
public static void bubbleSort(int[] arr) {
for (int x = 0; x < arr.length - 1; x++) { // 控制循環(huán)次數(shù)
for (int y = 0; y < arr.length - 1 - x; y++) {
if (arr[y] > arr[y + 1]) {
int temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}
}
52.xml的幾種解析方式區(qū)別是?
- SAX,速度最快,但無(wú)法進(jìn)行深層次解析
- DOM4J,可以進(jìn)行深層解析杜漠,效率低于SAX但高于其他解析方式
- DOM,可以進(jìn)行深層解析,效率低于DOM4J
- JDOM,可以進(jìn)行深層解析察净,效率低于DOM4J
53.多線程的幾種實(shí)現(xiàn)方式?
- 繼承Thread父類(lèi)
- 實(shí)現(xiàn)Runnable接口
54.UML圖中五種常用的圖分別是?
用例圖 類(lèi)圖 序列圖 行為圖 交互圖 ER圖
55.數(shù)據(jù)結(jié)構(gòu)分為哪兩種結(jié)構(gòu)?
- 線性結(jié)構(gòu):線性表驾茴、棧、隊(duì)列氢卡、串锈至、…
- 非線性結(jié)構(gòu):樹(shù)、圖译秦、…
56.TCP與UDP的區(qū)別?
- 1.基于連接與無(wú)連接
- 2.對(duì)系統(tǒng)資源的要求(TCP較多峡捡,UDP少)
- 3.UDP程序結(jié)構(gòu)較簡(jiǎn)單
- 4.流模式與數(shù)據(jù)報(bào)模式
- 5.TCP保證數(shù)據(jù)正確性,UDP可能丟包筑悴,TCP保證數(shù)據(jù)順序们拙,UDP不保證
57.通過(guò)startService()和bindService()啟動(dòng)service,service的生命周期上有哪些不同阁吝?
通過(guò)startService()啟動(dòng)服務(wù):會(huì)調(diào)用如下生命周期方法:
onCreate()---->onStart()---->onDestory()
如果是調(diào)用bindService()啟動(dòng)服務(wù):會(huì)調(diào)用如下生命周期方法:
onCreate()---->onBind---->onUnBind()---->onDestory()
不同點(diǎn)在于:當(dāng)采用startService()方法啟動(dòng)服務(wù)砚婆,訪問(wèn)者與服務(wù)之間是沒(méi)有綁定在一起的,訪問(wèn)者退出突勇,服務(wù)還在運(yùn)行装盯,而采用bindService()方法啟動(dòng)服務(wù)時(shí),訪問(wèn)者與服務(wù)是綁定在一起的与境,即訪問(wèn)者退出验夯,服務(wù)也就終止,解除綁定摔刁。
58.Activity的void onSavelnstanceState(Bundle outState)有什么作用挥转?如何使用?
作用:在系統(tǒng)回收Activty之前保存Activity當(dāng)前的狀態(tài),可用于存放程序臨時(shí)性的一些數(shù)據(jù)到磁盤(pán)中绑谣。
我們可以將要保存的數(shù)據(jù)存放在bundle對(duì)象中党窜。outState.putString(key, value);
59.請(qǐng)簡(jiǎn)述Android中UI thread、handler借宵、Message Queue幌衣、Looper之間的關(guān)系
Andriod提供了 Handler 和 Looper 來(lái)滿(mǎn)足線程間的通信。Handler遵循先進(jìn)先出的原則壤玫。
在單線程環(huán)境中豁护,UI thread 為主線程,默認(rèn)會(huì)創(chuàng)建一個(gè)Looper對(duì)象及由其管理的MessageQueue欲间, MessageQueue用來(lái)存放Message對(duì)象楚里。
你可以構(gòu)造Handler對(duì)象來(lái)與Looper溝通,Handler通過(guò)sendMessage()將Message傳遞給Looper猎贴,Looper會(huì)將消息放入MessageQueue中班缎。
當(dāng)Looper看到MessageQueue中含有Message,就將其廣播出去她渴。Handler對(duì)象收到消息后达址,調(diào)用handlerMessage()對(duì)其進(jìn)行處理。
60.請(qǐng)簡(jiǎn)述SurfaceView和View的區(qū)別
surfaceView它是在一個(gè)新起的單獨(dú)線程中重新繪制畫(huà)面而View必須在UI的主線程中更新畫(huà)面趁耗。
那么在UI的主線程中更新畫(huà)面沉唠,可能會(huì)引發(fā)問(wèn)題,比如你更新畫(huà)面的時(shí)間過(guò)長(zhǎng)对粪,那么你的主UI線程會(huì)被你正在畫(huà)的函數(shù)阻塞右冻。那么將無(wú)法響應(yīng)輸入的請(qǐng)求,將會(huì)導(dǎo)致引發(fā)ANR異常著拭!
當(dāng)使用surfaceView 由于是在新的線程中更新畫(huà)面所以不會(huì)阻塞你的UI主線程纱扭。但這也帶來(lái)了另外一個(gè)問(wèn)題,就是事件同步儡遮。比如你觸屏了一下乳蛾,你需要surfaceView中thread處理,一般就需要有一個(gè)event queue的設(shè)計(jì)來(lái)保存touch event鄙币,這會(huì)稍稍復(fù)雜一點(diǎn)肃叶,因?yàn)樯婕暗骄€程同步。
61.wait和sleep的比較?
sleep方法有:sleep(long millis)十嘿,sleep(long millis, long nanos)因惭,調(diào)用sleep方法后,當(dāng)前線程進(jìn)入休眠期绩衷,暫停執(zhí)行蹦魔,但該線程繼續(xù)擁有監(jiān)視資源的所有權(quán)激率。到達(dá)休眠時(shí)間后線程將繼續(xù)執(zhí)行,直到完成勿决。若在休眠期另一線程中斷該線程乒躺,則該線程退出。
wait方法有:wait()低缩,wait(long timeout)嘉冒,wait(long timeout, long nanos),調(diào)用wait方法后咆繁,該線程放棄監(jiān)視資源的所有權(quán)進(jìn)入等待狀態(tài)讳推;
wait():等待有其它的線程調(diào)用notify()或notifyAll()進(jìn)入調(diào)度狀態(tài),與其它線程共同爭(zhēng)奪監(jiān)視玩般。wait()相當(dāng)于wait(0)娜遵,wait(0, 0)。
wait(long timeout):當(dāng)其它線程調(diào)用notify()或notifyAll()壤短,或時(shí)間到達(dá)timeout亳秒,或有其它某線程中斷該線程慨仿,則該線程進(jìn)入調(diào)度狀態(tài)久脯。
wait(long timeout, long nanos):相當(dāng)于wait(1000000*timeout + nanos),只不過(guò)時(shí)間單位為納秒镰吆。
62.請(qǐng)描述下Activity的生命周期?
63.如果后臺(tái)的Activity由于某原因被系統(tǒng)回收了帘撰,如何在被系統(tǒng)回收之前保存當(dāng)前狀態(tài)?
利用onSaveInstanceState()方法保存狀態(tài) , 除了在棧頂?shù)腶ctivity,其他的activity都有可能在內(nèi)存不足的時(shí)候被系統(tǒng)回收,一個(gè)activity越處于棧底,被回收的可能性越大.
當(dāng)你的程序中某一個(gè)Activity A在運(yùn)行時(shí)万皿,主動(dòng)或被動(dòng)地運(yùn)行另一個(gè)新的Activity B摧找,這個(gè)時(shí)候A會(huì)執(zhí)行onSaveInstanceState()。B完成以后又會(huì)來(lái)找A牢硅,這個(gè)時(shí)候就有兩種情況:一是A被回收蹬耘,二是A沒(méi)有被回收,被回收的A就要重新調(diào)用onCreate()方法减余,不同于直接啟動(dòng)的是這回onCreate()里是帶上了參數(shù)savedInstanceState综苔;而沒(méi)被收回的就直接執(zhí)行onResume(),跳過(guò)onCreate()了位岔。
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("id", 1234567890);
}
public void onCreate(Bundle savedInstanceState) {
//判斷 savedInstanceState是不是空.
//如果不為空就取出來(lái)
super.onCreate(savedInstanceState);
}
64.如何退出Activity如筛?如何安全退出已調(diào)用多個(gè)Activity的Application?
對(duì)于單一Activity的應(yīng)用來(lái)說(shuō)抒抬,退出很簡(jiǎn)單杨刨,直接finish()即可。(用戶(hù)點(diǎn)擊back鍵 就是退出一個(gè)activity 退出activity 會(huì)執(zhí)行 onDestroy()方法 .當(dāng)然擦剑,也可以用killProcess()和System.exit()這樣的方法妖胀。
但是限佩,對(duì)于多Activity的應(yīng)用來(lái)說(shuō)脱惰,在打開(kāi)多個(gè)Activity后,如果想在最后打開(kāi)的Activity直接退出,上邊的方法都是沒(méi)有用的搀绣,因?yàn)樯线叺姆椒ǘ际墙Y(jié)束一個(gè)Activity而已。
那么峡钓,有沒(méi)有辦法直接退出整個(gè)應(yīng)用呢易迹?
在2.1之前,可以使用ActivityManager的restartPackage方法肉康。
它可以直接結(jié)束整個(gè)應(yīng)用闯估。在使用時(shí)需要權(quán)限android.permission.RESTART_PACKAGES。注意不要被它的名字迷惑吼和。可是涨薪,在2.2,這個(gè)方法失效了炫乓。在2.2添加了一個(gè)新的方法刚夺,killBackgroundProcesses(),需要權(quán)限 android.permission.KILL_BACKGROUND_PROCESSES末捣∠拦茫可惜的是,它和2.2的restartPackage一樣箩做,根本起不到應(yīng)有的效果莽红。
另外還有一個(gè)方法,就是系統(tǒng)自帶的應(yīng)用程序管理里邦邦,強(qiáng)制結(jié)束程序的方法安吁,forceStopPackage()。
它需要權(quán)限android.permission.FORCE_STOP_PACKAGES燃辖。并且需要添加android:sharedUserId="android.uid.system"屬性.同樣可惜的是鬼店,該方法是非公開(kāi)的,他只能運(yùn)行在系統(tǒng)進(jìn)程郭赐,第三方程序無(wú)法調(diào)用薪韩。因?yàn)樾枰贏ndroid.mk中添加LOCAL_CERTIFICATE := platform。而Android.mk是用于在Android源碼下編譯程序用的捌锭。從以上可以看出俘陷,在2.2,沒(méi)有辦法直接結(jié)束一個(gè)應(yīng)用观谦,而只能用自己的辦法間接辦到拉盾。現(xiàn)提供幾個(gè)方法,供參考:
- 拋異常強(qiáng)制退出:該方法通過(guò)拋異常豁状,使程序Force Close捉偏。驗(yàn)證可以倒得,但是,需要解決的問(wèn)題是夭禽,如何使程序結(jié)束掉霞掺,而不彈出Force Close的窗口。//安全結(jié)束進(jìn)程 android.os.Process.killProcess(android.os.Process.myPid());
- 記錄打開(kāi)的Activity:每打開(kāi)一個(gè)Activity讹躯,就記錄下來(lái)菩彬。在需要退出時(shí),關(guān)閉每一個(gè)Activity即可潮梯。List<Activity> lists ; 在Application 全集的環(huán)境里面 lists = new ArrayList<Activity>();每一個(gè)activity在執(zhí)行oncreate()方法的時(shí)候 lists.add(this);
Ondestory() lists.remove(this);lists.add(activity);for(Activity activity: lists){
activity.finish();
}
- 發(fā)送特定廣播:在需要結(jié)束應(yīng)用時(shí)骗灶,發(fā)送一個(gè)特定的廣播,每個(gè)Activity收到廣播后秉馏,關(guān)閉即可耙旦。
//給某個(gè)activity 注冊(cè)接受廣播的意圖 registerReceiver(receiver, filter) //如果接受到的是 關(guān)閉activity的廣播 就調(diào)用finish()方法 把當(dāng)前的activity finish()掉
- 遞歸退出 : 在打開(kāi)新的Activity時(shí)使用startActivityForResult,然后自己加標(biāo)志萝究,在onActivityResult中處理免都,遞歸關(guān)閉。OnActivityResult();
除了第一個(gè)帆竹,都是想辦法把每一個(gè)Activity都結(jié)束掉琴昆,間接達(dá)到目的。
但是這樣做同樣不完美馆揉。
你會(huì)發(fā)現(xiàn),如果自己的應(yīng)用程序?qū)γ恳粋€(gè)Activity都設(shè)置了nosensor抖拦,在兩個(gè)Activity結(jié)束的間隙升酣,sensor可能有效了。
但至少态罪,我們的目的達(dá)到了噩茄,而且沒(méi)有影響用戶(hù)使用。
為了編程方便复颈,最好定義一個(gè)Activity基類(lèi)绩聘,處理這些共通問(wèn)題。
65.如何啟用Service耗啦,如何停用Service凿菩。
Android中的service類(lèi)似于windows中的service,service一般沒(méi)有用戶(hù)操作界面帜讲,它運(yùn)行于系統(tǒng)中不容易被用戶(hù)發(fā)覺(jué)衅谷,可以使用它開(kāi)發(fā)如監(jiān)控之類(lèi)的程序。
一.步驟
- 繼承Service類(lèi) public class SMSService extends Service { }
- 在AndroidManifest.xml文件中的<application>節(jié)點(diǎn)里對(duì)服務(wù)進(jìn)行配置:<service android:name=".DemoService" />
二.Context.startService()和Context.bindService , 服務(wù)不能自己運(yùn)行似将,需要通過(guò)調(diào)用Context.startService()或Context.bindService()方法啟動(dòng)服務(wù)获黔。這兩個(gè)方法都可
以啟動(dòng)Service蚀苛,但是它們的使用場(chǎng)合有所不同。
- 使用startService()方法啟動(dòng)服務(wù)玷氏,調(diào)用者與服務(wù)之間沒(méi)有關(guān)連堵未,即使調(diào)用者退出了,服務(wù)仍然運(yùn)行盏触。使用bindService()方法啟用服務(wù)渗蟹,調(diào)用者與服務(wù)綁定在了一起,調(diào)用者一旦退出耻陕,服務(wù)也就終止拙徽。
- 采用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()方法。
- 采用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ù)及綁定(也就是說(shuō)onCreate()和onBind()方法并不會(huì)被多次調(diào)用)换薄。如果調(diào)用者希望與正在綁定的服務(wù)
解除綁定,可以調(diào)用unbindService()方法翔试,調(diào)用該方法也會(huì)導(dǎo)致系統(tǒng)調(diào)用服務(wù)的onUnbind()-->onDestroy()方法轻要。
三.Service的生命周期 , Service常用生命周期回調(diào)方法如下:
- onCreate() 該方法在服務(wù)被創(chuàng)建時(shí)調(diào)用,該方法只會(huì)被調(diào)用一次垦缅,無(wú)論調(diào)用多少次startService()或bindService()方法伦腐,服務(wù)也只被創(chuàng)建一次。
- onDestroy() 該方法在服務(wù)被終止時(shí)調(diào)用失都。
- Context.startService()啟動(dòng)Service有關(guān)的生命周期方法
- onStart() 只有采用Context.startService()方法啟動(dòng)服務(wù)時(shí)才會(huì)回調(diào)該方法柏蘑。該方法在服務(wù)開(kāi)始運(yùn)行時(shí)被調(diào)用幸冻。多次調(diào)用startService()方法盡管不會(huì)多次創(chuàng)建服務(wù),但onStart() 方法會(huì)被多次調(diào)用咳焚。
- Context.bindService()啟動(dòng)Service有關(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)用又官。
備注:
- 采用startService()啟動(dòng)服務(wù)
Intent intent = new Intent(DemoActivity.this, DemoService.class);
startService(intent); - 采用Context.bindService()啟動(dòng)服務(wù)
Intent intent = new Intent(DemoActivity.this, DemoService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
//unbindService(conn);//解除綁定
66.注冊(cè)廣播有幾種方式延刘,這些方式有何優(yōu)缺點(diǎn)?
Android廣播機(jī)制(兩種注冊(cè)方法), 在android下六敬,要想接受廣播信息碘赖,那么這個(gè)廣播接收器就得我們自己來(lái)實(shí)現(xiàn)了,我們可以繼承BroadcastReceiver外构,就可以有一個(gè)廣播接受器了普泡。有個(gè)接受器還不夠,我們還得重寫(xiě)B(tài)roadcastReceiver里面的onReceiver方法审编,當(dāng)來(lái)廣播的時(shí)候我們要干什么撼班,這就要我們自己來(lái)實(shí)現(xiàn),例如我們可以搞一個(gè)信息防火墻垒酬。具體的代碼:
public class SmsBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] object = (Object[]) bundle.get("pdus");
SmsMessage sms[] = new SmsMessage[object.length];
for (int i = 0; i < object.length; i++) {
sms[0] = SmsMessage.createFromPdu((byte[]) object[i]);
Toast.makeText(context, "來(lái)自" + sms[i].getDisplayOriginatingAddress() + " 的消息是:" + sms[i].getDisplayMessageBody(), Toast.LENGTH_SHORT).show();
}
//終止廣播砰嘁,在這里我們可以稍微處理,根據(jù)用戶(hù)輸入的號(hào)碼可以實(shí)現(xiàn)短信防火墻勘究。
abortBroadcast();
}
}
當(dāng)實(shí)現(xiàn)了廣播接收器般码,還要設(shè)置廣播接收器接收廣播信息的類(lèi)型,這里是信息:android.provider.Telephony.SMS_RECEIVED
我們就可以把廣播接收器注冊(cè)到系統(tǒng)里面乱顾,可以讓系統(tǒng)知道我們有個(gè)廣播接收器。
這里有兩種注冊(cè)方式宫静,一種是代碼動(dòng)態(tài)代碼注冊(cè):
//生成廣播處理
smsBroadCastReceiver = new SmsBroadCastReceiver();
//實(shí)例化過(guò)濾器并設(shè)置要過(guò)濾的廣播
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
//注冊(cè)廣播
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver, intentFilter);
一種是在AndroidManifest.xml文件中配置廣播
...
<!--廣播注冊(cè)-->
<receiver android:name=".SmsBroadCastReceiver">
<intent-filter android:priority="20">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
...
<!-- 權(quán)限申請(qǐng) -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
兩種注冊(cè)類(lèi)型的區(qū)別是:
- 第一種不是常駐型廣播走净,也就是說(shuō)廣播跟隨程序的生命周期。
- 第二種是常駐型孤里,也就是說(shuō)當(dāng)應(yīng)用程序關(guān)閉后伏伯,如果有信息廣播來(lái),程序也會(huì)被系統(tǒng)調(diào)用自動(dòng)運(yùn)行捌袜。
67.請(qǐng)談?wù)凙ndroid引入廣播機(jī)制的用意?
- 從MVC的角度考慮(應(yīng)用程序內(nèi)) 其實(shí)回答這個(gè)問(wèn)題的時(shí)候還可以這樣問(wèn)说搅,android為什么要有那4大組件,現(xiàn)在的移動(dòng)開(kāi)發(fā)模型基本上也是照搬的web那一套MVC架構(gòu)虏等,只不過(guò)是改了點(diǎn)嫁妝而已弄唧。android的四大組件本質(zhì)上就是為了實(shí)現(xiàn)移動(dòng)或者說(shuō)嵌入式設(shè)備上的MVC架構(gòu)适肠,它們之間有時(shí)候是一種相互依存的關(guān)系,有時(shí)候又是一種補(bǔ)充關(guān)系候引,引入廣播機(jī)制可以方便幾大組件的信息和數(shù)據(jù)交互侯养。
- 程序間互通消息(例如在自己的應(yīng)用程序內(nèi)監(jiān)聽(tīng)系統(tǒng)來(lái)電)
- 效率上(參考UDP的廣播協(xié)議在局域網(wǎng)的方便性)
- 設(shè)計(jì)模式上(反轉(zhuǎn)控制的一種應(yīng)用,類(lèi)似監(jiān)聽(tīng)者模式)
68.什么情況會(huì)導(dǎo)致Force Close ?如何避免?能否捕獲導(dǎo)致其的異常?
一般像空指針啊澄干,可以看起logcat逛揩,然后對(duì)應(yīng)到程序中 來(lái)解決錯(cuò)誤 .
69.橫豎屏切換時(shí)候Activity的生命周期?(實(shí)際驗(yàn)證與以下描述不太相符,都會(huì)重新調(diào)用一次生命周期方法)
這個(gè)生命周期跟清單文件里的配置有關(guān)系
- 不設(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方法
一般在游戲開(kāi)發(fā)中, 屏幕的朝向都是寫(xiě)死的.
70.如何將SQLite數(shù)據(jù)庫(kù)(dictionary.db文件)與apk文件一起發(fā)布?
可以將dictionary.db文件復(fù)制到Android工程中的res/raw目錄中炭懊。所有在res/raw目錄中的文件不會(huì)被壓縮,這樣可以直接提取該目錄中的文件拂檩。
71.如何打開(kāi)res/raw目錄中的數(shù)據(jù)庫(kù)文件?
在Android中不能直接打開(kāi)res/raw目錄中的數(shù)據(jù)庫(kù)文件侮腹,而需要在程序第一次啟動(dòng)時(shí)將該文件復(fù)制到手機(jī)內(nèi)存或SD卡的某個(gè)目錄中,然后再打開(kāi)該數(shù)據(jù)庫(kù)文件稻励。復(fù)制的基本方法是使用getResources().openRawResource方法獲得res/raw目錄中資源的 InputStream對(duì)象父阻,然后將該InputStream對(duì)象中的數(shù)據(jù)寫(xiě)入其他的目錄中相應(yīng)文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來(lái)打開(kāi)任意目錄中的SQLite數(shù)據(jù)庫(kù)文件望抽。
72.AIDL的全稱(chēng)是什么加矛?如何工作?能處理哪些類(lèi)型的數(shù)據(jù)煤篙?
AIDL的英文全稱(chēng)是Android Interface Define Language
當(dāng)A進(jìn)程要去調(diào)用B進(jìn)程中的service時(shí)斟览,并實(shí)現(xiàn)通信,我們通常都是通過(guò)AIDL來(lái)操作的
A工程:
首先我們?cè)趎et.blogjava.mobile.aidlservice包中創(chuàng)建一個(gè)RemoteService.aidl文件辑奈,在里面我們自定義一個(gè)接口苛茂,含有方法get。ADT插件會(huì)在gen目錄下自動(dòng)生成一個(gè)RemoteService.java文件鸠窗,該類(lèi)中含有一個(gè)名為RemoteService.stub的內(nèi)部類(lèi)妓羊,該內(nèi)部類(lèi)中含有aidl文件接口的get方法。
說(shuō)明一:aidl文件的位置不固定稍计,可以任意 , 然后定義自己的MyService類(lèi)躁绸,在MyService類(lèi)中自定義一個(gè)內(nèi)部類(lèi)去繼承RemoteService.stub這個(gè)內(nèi)部類(lèi),實(shí)現(xiàn)get方法。在onBind方法中返回這個(gè)內(nèi)部類(lèi)的對(duì)象净刮,系統(tǒng)會(huì)自動(dòng)將這個(gè)對(duì)象封裝成IBinder對(duì)象剥哑,傳遞給他的調(diào)用者。其次需要在AndroidManifest.xml文件中配置MyService類(lèi)庭瑰,代碼如下:
<!-- 注冊(cè)服務(wù) -->
<service android:name=".MyService">
<intent-filter>
<!-- 指定調(diào)用AIDL服務(wù)的ID -->
<action android:name="net.blogjava.mobile.aidlservice.RemoteService" />
</intent-filter>
</service>
為什么要指定調(diào)用AIDL服務(wù)的ID ? 就是要告訴外界MyService這個(gè)類(lèi)能夠被別的進(jìn)程訪問(wèn)星持,只要?jiǎng)e的進(jìn)程知道這個(gè)ID,正是有了這個(gè)ID,B工程才能找到A工程實(shí)現(xiàn)通信弹灭。
說(shuō)明:AIDL并不需要權(quán)限
B工程:首先我們要將A工程中生成的RemoteService.java文件拷貝到B工程中督暂,在bindService方法中綁定aidl服務(wù) , 綁定AIDL服務(wù)就是將RemoteService的ID作為intent的action參數(shù)。
說(shuō)明:如果我們單獨(dú)將RemoteService.aidl文件放在一個(gè)包里穷吮,那個(gè)在我們將gen目錄下的該包拷貝到B工程中逻翁。如果我們將RemoteService.aidl文件和我們的其他類(lèi)存放在一起,那么我們?cè)贐工程中就要建立相應(yīng)的包捡鱼,以保證RmoteService.java文件的包名正確八回,我們不能修改RemoteService.java文件
bindService(new Inten("net.blogjava.mobile.aidlservice.RemoteService"), serviceConnection, Context.BIND_AUTO_CREATE);
ServiceConnection的onServiceConnected(ComponentName name, IBinder service)方法中的service參數(shù)就是A工程中MyService類(lèi)中繼承了RemoteService.stub類(lèi)的內(nèi)部類(lèi)的對(duì)象。
73.請(qǐng)解釋下在單線程模型中Message驾诈、Handler缠诅、Message Queue、Looper之間的關(guān)系乍迄。
- Handler簡(jiǎn)介:一個(gè)Handler允許你發(fā)送和處理Message和Runable對(duì)象管引,這些對(duì)象和一個(gè)線程的MessageQueue相關(guān)聯(lián)。每一個(gè)線程實(shí)例和一個(gè)單獨(dú)的線程以及該線程的MessageQueue相關(guān)聯(lián)闯两。當(dāng)你創(chuàng)建一個(gè)新的Handler時(shí)褥伴,它就和創(chuàng)建它的線程綁定在一起了。這里漾狼,線程我們也可以理解為線程的MessageQueue重慢。從這一點(diǎn)上來(lái)看,Handler把Message和Runable對(duì)象傳遞給MessageQueue逊躁,而且在這些對(duì)象離開(kāi)MessageQueue時(shí)似踱,Handler負(fù)責(zé)執(zhí)行他們。
Handler有兩個(gè)主要的用途:
+ 確定在將來(lái)的某個(gè)時(shí)間點(diǎn)執(zhí)行一個(gè)或者一些Message和Runnable對(duì)象稽煤。
+ 在其他線程(不是Handler綁定線程)中排入一些要執(zhí)行的動(dòng)作核芽。
Scheduling Message,即(1)念脯,可以通過(guò)以下方法完成:
+ post(Runnable):Runnable在handler綁定的線程上執(zhí)行,也就是說(shuō)不創(chuàng)建新線程弯淘。
+ postAtTime(Runnable,long):
+ postDelayed(Runnable,long):
+ sendEmptyMessage(int):
+ sendMessage(Message):
+ sendMessageAtTime(Message,long):
+ sendMessageDelayed(Message,long):
+ post這個(gè)動(dòng)作讓你把Runnable對(duì)象排入MessageQueue,MessageQueue收到這些消息的時(shí)候執(zhí)行他們绿店,當(dāng)然以一定的排序。sendMessage這個(gè)動(dòng)作允許你把Message對(duì)象排成隊(duì)列,這些Message對(duì)象包含一些信息假勿,Handler的hanlerMessage(Message)會(huì)處理這些Message.當(dāng)然借嗽,handlerMessage(Message)必須由Handler的子類(lèi)來(lái)重寫(xiě)。這是編程人員需要作的事转培。
當(dāng)posting或者sending到一個(gè)Hanler時(shí)恶导,你可以有三種行為:當(dāng)MessageQueue準(zhǔn)備好就處理,定義一個(gè)延遲時(shí)間浸须,定義一個(gè)精確的時(shí)間去處理惨寿。后兩者允許你實(shí)現(xiàn)timeout,tick,和基于時(shí)間的行為。
當(dāng)你的應(yīng)用創(chuàng)建一個(gè)新的進(jìn)程時(shí)删窒,主線程(也就是UI線程)自帶一個(gè)MessageQueue裂垦,這個(gè)MessageQueue管理頂層的應(yīng)用對(duì)象(像activities,broadcast receivers等)和主線程創(chuàng)建的窗體。你可以創(chuàng)建自己的線程肌索,并通過(guò)一個(gè)Handler和主線程進(jìn)行通信蕉拢。這和之前一樣,通過(guò)post和send message來(lái)完成诚亚,差別在于在哪一個(gè)線程中執(zhí)行這個(gè)方法晕换。在恰當(dāng)?shù)臅r(shí)候,給定的Runnable和Message將在Handler的MessageQueue中被Scheduled站宗。
- Message簡(jiǎn)介:Message類(lèi)就是定義了一個(gè)信息闸准,這個(gè)信息中包含一個(gè)描述符和任意的數(shù)據(jù)對(duì)象,這個(gè)信息被用來(lái)傳遞給Handler.Message對(duì)象提供額外的兩個(gè)int域和一個(gè)Object域份乒,這可以讓你在大多數(shù)情況下不用作分配的動(dòng)作恕汇。盡管Message的構(gòu)造函數(shù)是public的,但是獲取Message實(shí)例的最好方法是調(diào)用Message.obtain(),或者Handler.obtainMessage()方法或辖,這些方法會(huì)從回收對(duì)象池中獲取一個(gè)瘾英。
- MessageQueue簡(jiǎn)介:
這是一個(gè)包含message列表的底層類(lèi)。Looper負(fù)責(zé)分發(fā)這些message颂暇。Messages并不是直接加到一個(gè)MessageQueue中缺谴,而是通過(guò)MessageQueue.IdleHandler關(guān)聯(lián)到Looper。
你可以通過(guò)Looper.myQueue()從當(dāng)前線程中獲取MessageQueue耳鸯。
- Looper簡(jiǎn)介:
Looper類(lèi)被用來(lái)執(zhí)行一個(gè)線程中的message循環(huán)湿蛔。默認(rèn)情況,沒(méi)有一個(gè)消息循環(huán)關(guān)聯(lián)到線程县爬。在線程中調(diào)用prepare()創(chuàng)建一個(gè)Looper阳啥,然后用loop()來(lái)處理messages,直到循環(huán)終止财喳。
大多數(shù)和message loop的交互是通過(guò)Handler察迟。
下面是一個(gè)典型的帶有Looper的線程實(shí)現(xiàn)斩狱。
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
74.你如何評(píng)價(jià)Android系統(tǒng)??jī)?yōu)缺點(diǎn)扎瓶。
Android平臺(tái)手機(jī) 5大優(yōu)勢(shì):
一所踊、開(kāi)放性 (開(kāi)源 ophone 阿里云( 完全兼容android) 樂(lè)os )
在優(yōu)勢(shì)方面,Android平臺(tái)首先就是其開(kāi)發(fā)性概荷,開(kāi)發(fā)的平臺(tái)允許任何移動(dòng)終端廠商加入到Android聯(lián)盟中來(lái)秕岛。顯著的開(kāi)放性可以使其擁有更多的開(kāi)發(fā)者,隨著用戶(hù)和應(yīng)用的日益豐富误证,一個(gè)嶄新的平臺(tái)也將很快走向成熟继薛。開(kāi)放性對(duì)于Android的發(fā)展而言,有利于積累人氣雷厂,這里的人氣包括消費(fèi)者和廠商惋增,而對(duì)于消費(fèi)者來(lái)講,隨大的受益正是豐富的軟件資源改鲫。開(kāi)放的平臺(tái)也會(huì)帶來(lái)更大競(jìng)爭(zhēng)诈皿,如此一來(lái),消費(fèi)者將可以用更低的價(jià)位購(gòu)得心儀的手機(jī)像棘。
二稽亏、掙脫運(yùn)營(yíng)商的束縛
在過(guò)去很長(zhǎng)的一段時(shí)間,特別是在歐美地區(qū)缕题,手機(jī)應(yīng)用往往受到運(yùn)營(yíng)商制約截歉,使用什么功能接入什么網(wǎng)絡(luò),幾乎都受到運(yùn)營(yíng)商的控制烟零。從去年iPhone 上市 瘪松,用戶(hù)可以更加方便地連接網(wǎng)絡(luò),運(yùn)營(yíng)商的制約減少锨阿。隨著EDGE宵睦、HSDPA這些2G至3G移動(dòng)網(wǎng)絡(luò)的逐步過(guò)渡和提升,手機(jī)隨意接入網(wǎng)絡(luò)已不是運(yùn)營(yíng)商口中的笑談墅诡,當(dāng)你可以通過(guò)手機(jī)IM軟件方便地進(jìn)行即時(shí)聊天時(shí)壳嚎,再回想不久前天價(jià)的彩信和圖鈴下載業(yè)務(wù),是不是像噩夢(mèng)一樣末早?互聯(lián)網(wǎng)巨頭Google推動(dòng)的Android終端天生就有網(wǎng)絡(luò)特色烟馅,將讓用戶(hù)離互聯(lián)網(wǎng)更近。
三然磷、豐富的硬件選擇 (mtk android)
這一點(diǎn)還是與Android平臺(tái)的開(kāi)放性相關(guān)郑趁,由于Android的開(kāi)放性,眾多的廠商會(huì)推出千奇百怪姿搜,功能特色各具的多種產(chǎn)品寡润。功能上的差異和特色缺脉,卻不會(huì)影響到數(shù)據(jù)同步、甚至軟件的兼容悦穿,好比你從諾基亞 Symbian風(fēng)格手機(jī) 一下改用蘋(píng)果 iPhone ,同時(shí)還可將Symbian中優(yōu)秀的軟件帶到iPhone上使用业踢、聯(lián)系人等資料更是可以方便地轉(zhuǎn)移栗柒,是不是非常方便呢?
四知举、不受任何限制的開(kāi)發(fā)商
Android平臺(tái)提供給第三方開(kāi)發(fā)商一個(gè)十分寬泛瞬沦、自由的環(huán)境,不會(huì)受到各種條條框框的阻擾雇锡,可想而知逛钻,會(huì)有多少新穎別致的軟件會(huì)誕生。但也有其兩面性锰提,血腥曙痘、暴力、情色方面的程序和游戲如可控制正是留給Android難題之一立肘。
五边坤、無(wú)縫結(jié)合的Google應(yīng)用
如今叱詫互聯(lián)網(wǎng)的Google已經(jīng)走過(guò)10年度歷史,從搜索巨人到全面的互聯(lián)網(wǎng)滲透谅年,Google服務(wù)如地圖茧痒、郵件、搜索等已經(jīng)成為連接用戶(hù)和互聯(lián)網(wǎng)的重要紐帶融蹂,而Android平臺(tái)手機(jī)將無(wú)縫結(jié)合這些優(yōu)秀的Google服務(wù)旺订。
再說(shuō)Android的5大不足:
一、安全和隱私
由于手機(jī) 與互聯(lián)網(wǎng)的緊密聯(lián)系超燃,個(gè)人隱私很難得到保守区拳。除了上網(wǎng)過(guò)程中經(jīng)意或不經(jīng)意留下的個(gè)人足跡,Google這個(gè)巨人也時(shí)時(shí)站在你的身后淋纲,洞穿一切劳闹,因此,互聯(lián)網(wǎng)的深入將會(huì)帶來(lái)新一輪的隱私危機(jī)洽瞬。
二本涕、首先開(kāi)賣(mài)Android手機(jī)的不是最大運(yùn)營(yíng)商
眾所周知,T-Mobile在23日伙窃,于美國(guó)紐約發(fā)布 了Android首款手機(jī)G1菩颖。但是在北美市場(chǎng),最大的兩家運(yùn)營(yíng)商乃AT&T和Verizon,而目前所知取得Android手機(jī)銷(xiāo)售權(quán)的僅有 T-Mobile和Sprint连茧,其中T-Mobile的3G網(wǎng)絡(luò)相對(duì)于其他三家也要遜色不少,因此串结,用戶(hù)可以買(mǎi)賬購(gòu)買(mǎi)G1呻右,能否體驗(yàn)到最佳的3G網(wǎng)絡(luò)服務(wù)則要另當(dāng)別論了跪妥!
三、運(yùn)營(yíng)商仍然能夠影響到Android手機(jī)
在國(guó)內(nèi)市場(chǎng)声滥,不少用戶(hù)對(duì)購(gòu)得移動(dòng)定制機(jī)不滿(mǎn)眉撵,感覺(jué)所購(gòu)的手機(jī)被人涂畫(huà)了廣告一般。這樣的情況在國(guó)外市場(chǎng)同樣出現(xiàn)落塑。Android手機(jī)的另一發(fā)售運(yùn)營(yíng)商Sprint就將在其機(jī)型中內(nèi)置其手機(jī)商店程序纽疟。
四、同類(lèi)機(jī)型用戶(hù)減少 (山寨化嚴(yán)重)
在不少手機(jī)論壇都會(huì)有針對(duì)某一型號(hào)的子論壇憾赁,對(duì)一款手機(jī)的使用心得交流污朽,并分享軟件資源。而對(duì)于Android平臺(tái)手機(jī)龙考,由于廠商豐富蟆肆,產(chǎn)品類(lèi)型多樣,這樣使用同一款機(jī)型的用戶(hù)越來(lái)越少晦款,缺少統(tǒng)一機(jī)型的程序強(qiáng)化颓芭。舉個(gè)稍顯不當(dāng)?shù)睦樱F(xiàn)在山寨機(jī)泛濫柬赐,品種各異亡问,就很少有專(zhuān)門(mén)針對(duì)某個(gè)型號(hào)山寨機(jī)的討論和群組,除了哪些功能異常搶眼肛宋、頗受追捧的機(jī)型以外州藕。
五、過(guò)分依賴(lài)開(kāi)發(fā)商缺少標(biāo)準(zhǔn)配置
在使用PC端的Windows Xp系統(tǒng)的時(shí)候酝陈,都會(huì)內(nèi)置微軟Windows Media Player這樣一個(gè)瀏覽器程序床玻,用戶(hù)可以選擇更多樣的播放器,如Realplay或暴風(fēng)影音等沉帮。但入手開(kāi)始使用默認(rèn)的程序同樣可以應(yīng)付多樣的需要锈死。在 Android平臺(tái)中,由于其開(kāi)放性穆壕,軟件更多依賴(lài)第三方廠商待牵,比如Android系統(tǒng)的SDK中就沒(méi)有內(nèi)置音樂(lè) 播放器,全部依賴(lài)第三方開(kāi)發(fā)喇勋,缺少了產(chǎn)品的統(tǒng)一性缨该。
75.嵌入式操作系統(tǒng)內(nèi)存管理有哪幾種, 各有何特性?
頁(yè)式川背,段式贰拿,段頁(yè)蛤袒,用到了MMU,虛擬空間等技術(shù)
76.java中如何引用本地語(yǔ)言?
可以用JNI(java native interface java 本地接口)接口 。
77.談?wù)凙ndroid的IPC(進(jìn)程間通信)機(jī)制
IPC是內(nèi)部進(jìn)程通信的簡(jiǎn)稱(chēng)膨更, 是共享"命名管道"的資源妙真。Android中的IPC機(jī)制是為了讓Activity和Service之間可以隨時(shí)的進(jìn)行交互,故在Android中該機(jī)制荚守,只適用于Activity和Service之間的通信隐孽,類(lèi)似于遠(yuǎn)程方法調(diào)用,類(lèi)似于C/S模式的訪問(wèn)健蕊。通過(guò)定義AIDL接口文件來(lái)定義IPC接口。Servier端實(shí)現(xiàn)IPC接口踢俄,Client端調(diào)用IPC接口本地代理缩功。
78.請(qǐng)解釋下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))
79. View的刷新?
- 在需要刷新的地方,使用handle.sendmessage發(fā)送信息,然后在handle的handleMessage里面執(zhí)行invaliate或者postinvaliate.
- android中實(shí)現(xiàn)view的更新有兩個(gè)方法,一個(gè)是invalidate都办,另一個(gè)是postInvalidate嫡锌,其中前者是在UI線程自身中使用,而后者在非UI線程中使用琳钉。
80.Android系統(tǒng)中GC在什么情況下會(huì)出現(xiàn)內(nèi)存泄漏呢势木?(內(nèi)存泄漏是指分配出去的內(nèi)存無(wú)法回收了(導(dǎo)致內(nèi)存資源耗盡),一個(gè)是收不回,一個(gè)是要的太多給不了歌懒,系統(tǒng)負(fù)擔(dān)不起啦桌。)
- 數(shù)據(jù)庫(kù)的cursor沒(méi)有關(guān)閉
- 構(gòu)造adapter時(shí),沒(méi)有使用緩存contentview
- 衍生listview的優(yōu)化問(wèn)題-----減少創(chuàng)建view的對(duì)象,充分使用contentview,可以使用一靜態(tài)類(lèi)來(lái)優(yōu)化處理getview的過(guò)程
- Bitmap對(duì)象不使用時(shí)采用recycle()釋放內(nèi)存
- 調(diào)用registerReceiver后未調(diào)用unregisterReceiver()。
- 未關(guān)閉InputStream/OutputStream及皂。
- Context泄漏甫男。
- activity中的對(duì)象的生命周期大于activity
- 調(diào)試方法: DDMS==> HEAPSZIE==>dataobject==>[Total Size]
81.通過(guò)Intent傳遞一些二進(jìn)制數(shù)據(jù)的方法有哪些?
- 使用Serializable接口實(shí)現(xiàn)序列化,這是Java常用的方法验烧。
- 實(shí)現(xiàn)Parcelable接口板驳,這里Android的部分類(lèi)比如Bitmap類(lèi)就已經(jīng)實(shí)現(xiàn)了,同時(shí)Parcelable在Android AIDL中交換數(shù)據(jù)也很常見(jiàn)的碍拆。
82.Activity和Task的啟動(dòng)模式有哪些? 每種含義是什么?
有關(guān)在AndroidManifest.xml中的android:launchMode定義若治,主要有standard、singleTop感混、singleTask和singleInstance端幼,同時(shí)對(duì)于android:taskAffinity這些問(wèn)題大家也要了解,Android開(kāi)發(fā)網(wǎng)在以前的文章中講過(guò)弧满,不過(guò)很多開(kāi)發(fā)者仍然不是很清楚静暂,這些基礎(chǔ)問(wèn)題我們以后仍然會(huì)再次總結(jié)。
83.Intent的幾種有關(guān)Activity啟動(dòng)的方式有哪些谱秽,你了解每個(gè)含義嗎?
Intent的一些標(biāo)記有FLAG_ACTIVITY_BROUGHT_TO_FRONT 洽蛀、FLAG_ACTIVITY_CLEAR_TOP摹迷、FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET、FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS郊供、FLAG_ACTIVITY_MULTIPLE_TASK和FLAG_ACTIVITY_NEW_TASK 等峡碉。每種含義大家看SDK文檔和具體跑下這樣你的記憶會(huì)更深刻些。
84.Android都有哪些XML解析器驮审,都熟練掌握嗎?
這里XmlPull鲫寄、SAX和DOM相信做過(guò)Web開(kāi)發(fā)的都已經(jīng)滾瓜爛熟了。
85.說(shuō)說(shuō)HashSet和HashTable的區(qū)別
HashSet相對(duì)于HashMap就是不能存放重復(fù)的數(shù)據(jù)疯淫,對(duì)于HashTable來(lái)說(shuō)地来,存放的數(shù)據(jù)不能出現(xiàn)key或value為null這樣的情況。
86.android的操作系統(tǒng)根據(jù)進(jìn)程的優(yōu)先級(jí) 把進(jìn)程分為了若干個(gè)等級(jí)
- Foreground process 前臺(tái)進(jìn)程 ,就是用戶(hù)可以看到的熙掺,優(yōu)先級(jí)是最高的未斑,即便是在內(nèi)存不足的時(shí)候,系統(tǒng)也不會(huì)去殺死這個(gè)進(jìn)程
- Visible process 可見(jiàn)進(jìn)程 , 如果內(nèi)存不足币绩,會(huì)把比可見(jiàn)進(jìn)程優(yōu)先級(jí)低的進(jìn)程給殺死
- Service process 如果一個(gè)程序只有一個(gè)后臺(tái)的服務(wù)
- Background process 沒(méi)有服務(wù)的進(jìn)程 ,并且我們用戶(hù)看不見(jiàn)這個(gè)進(jìn)程
- Empty process 沒(méi)有任何活動(dòng)組件的進(jìn)程 . 為了在使用這個(gè)進(jìn)程的時(shí)候蜡秽,能夠更快的創(chuàng)建出來(lái),所以默認(rèn)情況不會(huì)殺死一個(gè)進(jìn)程缆镣,那么這個(gè)進(jìn)程就是一個(gè)empty的進(jìn)程芽突。
87.隱式、顯式Intent的區(qū)別
- 顯式意圖 , 通過(guò)名字指明目標(biāo)組件(這個(gè)組件名字字段component name field, 前面提到過(guò), 有一個(gè)數(shù)值集)董瞻。既然組件名稱(chēng)通常不為其他應(yīng)用程序的開(kāi)發(fā)者所了解寞蚌,顯式意圖典型的被用作應(yīng)用程序的內(nèi)部消息-例如一個(gè)活動(dòng)啟動(dòng) , 一個(gè)附屬服務(wù)或姊妹活動(dòng)
- 隱式意圖 , 不命名目標(biāo)組件(組件名稱(chēng)字段為空)。隱式意圖經(jīng)常用來(lái)激活其他應(yīng)用程序的組件钠糊。
88.DDMS和TraceView的區(qū)別?
DDMS是一個(gè)程序執(zhí)行查看器睬澡,在里面可以看見(jiàn)線程和堆棧等信息,TraceView是程序性能分析器,Traceview是android平臺(tái)配備一個(gè)很好的性能分析的工具眠蚂。它可以通過(guò)圖形化的方式讓我們了解我們要跟蹤的程序的性能煞聪,并且能具體到method。逝慧。
89.Dalvik和標(biāo)準(zhǔn)Java虛擬機(jī)之間的主要差別昔脯?
Dalvik和標(biāo)準(zhǔn)Java虛擬機(jī)(JVM)之間的首要差別之一,就是Dalvik基于寄存器笛臣,而JVM基于棧云稚。
Dalvik和Java之間的另外一大區(qū)別就是運(yùn)行環(huán)境——Dalvik經(jīng)過(guò)優(yōu)化,允許在有限的內(nèi)存中同時(shí)運(yùn)行多個(gè)虛擬機(jī)的實(shí)例沈堡,并且每一個(gè) Dalvik應(yīng)用作為一個(gè)獨(dú)立的Linux進(jìn)程執(zhí)行静陈。
- 虛擬機(jī)很小,使用的空間也小鲸拥;
- Dalvik沒(méi)有JIT編譯器拐格;
- 常量池已被修改為只使用32位的索引,以簡(jiǎn)化解釋器刑赶;
- 它使用自己的字節(jié)碼捏浊,而非Java字節(jié)碼。
90.簡(jiǎn)述SoundPool類(lèi)和MediaPlayer的使用有什么要注意的地方撞叨?
91.簡(jiǎn)述什么是雙緩沖金踪?
閃爍是圖形編程的一個(gè)常見(jiàn)問(wèn)題。當(dāng)進(jìn)行復(fù)雜的繪制操作時(shí)會(huì)導(dǎo)致呈現(xiàn)的圖像閃爍或具有其他不可接受的外觀牵敷。雙緩沖的使用解決這些問(wèn)題胡岔。雙緩沖使用內(nèi)存緩沖區(qū)來(lái)解決由多重繪制操作造成的閃爍問(wèn)題。當(dāng)使用雙緩沖時(shí)枷餐,首先在內(nèi)存緩沖區(qū)里完成所有繪制操作靶瘸,而不是在屏幕上直接進(jìn)行繪圖。當(dāng)所有繪制操作完成后尖淘,把內(nèi)存緩沖區(qū)完成的圖像直接復(fù)制到屏幕。因?yàn)樵谄聊簧现粓?zhí)行一個(gè)圖形操作著觉,所以消除了由復(fù)雜繪制操作造成的圖像閃爍問(wèn)題村生。
在android中實(shí)現(xiàn)雙緩沖,可以使用一個(gè)后臺(tái)畫(huà)布backcanvas,先把所有繪制操作都在這上面進(jìn)行。等圖畫(huà)好了饼丘,然后在把backcanvas拷貝到
與屏幕關(guān)聯(lián)的canvas上去,如下:
Bitmap bitmapBase = new Bitmap()
Canvas backcanvas = new Canvas(bitmapBase)
backcanvas.draw()...//畫(huà)圖
Canvas c = lockCanvas(null);
c.drawbitmap(bitmapBase);//把已經(jīng)畫(huà)好的圖像輸出到屏幕上
unlock(c)....
92.SQLite支持事務(wù)嗎趁桃?添加刪除如何提高性能?
SQLite作為輕量級(jí)的數(shù)據(jù)庫(kù)肄鸽,比MySQL還小卫病,但支持SQL語(yǔ)句查詢(xún),提高性能可以考慮通過(guò)原始經(jīng)過(guò)優(yōu)化的SQL查詢(xún)語(yǔ)句方式處理.
93.View典徘、SurfaceView蟀苛、GLSurFaceView 有什么區(qū)別
- view最基礎(chǔ)的,必須在UI主線程內(nèi)更新畫(huà)面逮诲,速度較慢帜平。
- SurfaceView 是view的子類(lèi) 類(lèi)似使用雙緩機(jī)制 快速刷新界面 速度比view快
- GLSurfaceView 是SurfaceView的子類(lèi)openGL專(zhuān)用的
94.以下代碼正確嗎?
interface A{
int x = 0;
}
class B {
int x = 1;
}
class C extends B implements A{
public void printX(){
System.out.println(x);
}
}
public class Main{
public static void main(String[] args){
new C().printX();
}
}
問(wèn)輸出結(jié)果是?
答案是編譯不通過(guò),報(bào)錯(cuò)The field x is ambiguous(字段x是不明確的 )
95.String a = "a";String b = "a";問(wèn)a==b是否為true?
為true
96.同一個(gè)程序梅鹦,但不同的Activity是否可以放在不同的Task任務(wù)棧中裆甩?
可以. 比方說(shuō)在激活一個(gè)新的activity時(shí)候, 給intent設(shè)置flag , Intent的flag添加FLAG_ACTIVITY_NEW_TASK(intent.setFlag()),這個(gè)被激活的activity就會(huì)在新的task棧里面…
97.系統(tǒng)上安裝了多種瀏覽器,能否指定某瀏覽器訪問(wèn)指定頁(yè)面齐唆?
找到對(duì)應(yīng)的瀏覽器的意圖,傳遞數(shù)據(jù)URI , 激活這個(gè)意圖
98.請(qǐng)繼承SQLiteOpenHelper實(shí)現(xiàn):
1)創(chuàng)建一個(gè)版本為1的“diaryOpenHelper.db”的數(shù)據(jù)庫(kù)嗤栓,
2)同時(shí)創(chuàng)建一個(gè) "diary"表(包含一個(gè)_id主鍵并自增長(zhǎng),topic字符型100長(zhǎng)度,content字符型1000長(zhǎng)度)
3)在數(shù)據(jù)庫(kù)版本變化時(shí)請(qǐng)刪除diary表箍邮,并重新創(chuàng)建出diary表茉帅。
public class MyDbHelper extends SQLiteOpenHelper {
public final static String DATABASENAME = "diaryOpenHelper.db";
public final static int DATABASEVERSION = 1;
//創(chuàng)建數(shù)據(jù)庫(kù)
public MyDbHelper(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, DATABASENAME, factory, DATABASEVERSION);
}
//創(chuàng)建表等機(jī)構(gòu)性文件
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table diary" + "(" + "_id integer primary key autoincrement," + "topic varchar(100)," + "content varchar(1000)" + ")";
db.execSQL(sql);
}
//若數(shù)據(jù)庫(kù)版本有更新叨叙,則調(diào)用此方法
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String sql = "drop table if exists diary";
db.execSQL(sql);
this.onCreate(db);
}
}
99.為什么要用ContentProvider?它和sql的實(shí)現(xiàn)上有什么差別担敌?
- 屏蔽數(shù)據(jù)存儲(chǔ)的細(xì)節(jié),對(duì)用戶(hù)透明,用戶(hù)只需要關(guān)心操作數(shù)據(jù)的uri就可以了
- 不同app之間共享,操作數(shù)據(jù)
- Sql也有增刪改查的方法.
- 但是contentprovider 還可以去增刪改查本地文件.
100.什么時(shí)候使用Service摔敛?
擁有service的進(jìn)程具有較高的優(yōu)先級(jí),官方文檔告訴我們,Android系統(tǒng)會(huì)盡量保持擁有service的進(jìn)程運(yùn)行全封,只要在該service已經(jīng)被啟動(dòng)(start)或者客戶(hù)端連接(bindService)到它马昙。當(dāng)內(nèi)存不足時(shí),需要保持刹悴,擁有service的進(jìn)程具有較高的優(yōu)先級(jí)行楞。
- 如果service正在調(diào)用onCreate, onStartCommand或者onDestory方法,那么用于當(dāng)前service的進(jìn)程相當(dāng)于前臺(tái)進(jìn)程以避免被killed土匀。
- 如果當(dāng)前service已經(jīng)被啟動(dòng)(start)子房,擁有它的進(jìn)程則比那些用戶(hù)可見(jiàn)的進(jìn)程優(yōu)先級(jí)低一些,但是比那些不可見(jiàn)的進(jìn)程更重要就轧,這就意味著service一般不會(huì)被killed.
- 如果客戶(hù)端已經(jīng)連接到service (bindService),那么擁有Service的進(jìn)程則擁有最高的優(yōu)先級(jí)证杭,可以認(rèn)為service是可見(jiàn)的。
- 如果service可以使用startForeground(int, Notification)方法來(lái)將service設(shè)置為前臺(tái)狀態(tài)妒御,那么系統(tǒng)就認(rèn)為是對(duì)用戶(hù)可見(jiàn)的解愤,并不會(huì)在內(nèi)存不足時(shí)killed。
如果有其他的應(yīng)用組件作為Service,Activity等運(yùn)行在相同的進(jìn)程中乎莉,那么將會(huì)增加該進(jìn)程的重要性送讲。
1.Service的特點(diǎn)可以讓他在后臺(tái)一直運(yùn)行,可以在service里面創(chuàng)建線程去完成耗時(shí)的操作.
2.Broadcast receiver捕獲到一個(gè)事件之后,可以起一個(gè)service來(lái)完成一個(gè)耗時(shí)的操作.
3.遠(yuǎn)程的service如果被啟動(dòng)起來(lái),可以被多次bind, 但不會(huì)重新create. 索愛(ài)手機(jī)X10i的人臉識(shí)別的service可以被圖庫(kù)使用,可以被攝像機(jī),照相機(jī)等程序使用.
101.LayoutInflater 的創(chuàng)建方法?
- 系統(tǒng)服務(wù)LayoutInflater inflater = (LayoutInflater)Context.getSystemService(LAYOUT_INFLATER_SERVICE);
- 使用靜態(tài)的from()方法LayoutInflater layoutInflater=LayoutInflater.from(Context);
- 使用Activity中的getLayoutInflater()方法,返回填充器LayoutInflater layoutInflater=getLayoutInflater();
102.res/raw與assets的區(qū)別
- res/raw不能有子文件惋啃,自動(dòng)在R中生成ID哼鬓,調(diào)用 Resources.openResource方法,控制文件流進(jìn)行操作边灭。
- assets异希,可以有子文件,必須要提供一個(gè)文件名和文件目錄绒瘦,使用AssetManager來(lái)打開(kāi)文件操作宠互。不需要提供一個(gè)資源ID。
103.調(diào)用與被調(diào)用:我們的通信使者Intent
Intent就是意圖的意思 椭坚,應(yīng)用程序間使用Intent進(jìn)行交流予跌,打個(gè)電話啦,來(lái)個(gè)電話啦都會(huì)發(fā)Intent, 這個(gè)是Android架構(gòu)的松耦合的精髓部分善茎,大大提高了組件的復(fù)用性券册,比如你要在你的應(yīng)用程序中點(diǎn)擊按鈕,給某人打電話,很簡(jiǎn)單啊烁焙,看下代碼先:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + number));
startActivity(intent);
扔出這樣一個(gè)意圖航邢,系統(tǒng)看到了你的意圖就喚醒了電話撥號(hào)程序,打出來(lái)電話骄蝇。什么讀聯(lián)系人膳殷,發(fā)短信啊,郵件啊九火,統(tǒng)統(tǒng)只需要扔出intent就好了赚窃,這個(gè)部分設(shè)計(jì)地確實(shí)很好啊。
那Intent通過(guò)什么來(lái)告訴系統(tǒng)需要誰(shuí)來(lái)接受他呢?通常使用Intent有兩種方法岔激,第一種是直接說(shuō)明需要哪一個(gè)類(lèi)來(lái)接收代碼如下:
Intent intent = new Intent(this, MyActivity.class);
intent.getExtras().putString("id", "1");
tartActivity(intent);
第一種方式很明顯勒极,直接指定了MyActivity為接受者,并且傳了一些數(shù)據(jù)給MyActivity,在MyActivity里可以用getIntent()來(lái)得到這個(gè)intent和數(shù)據(jù)虑鼎。
第二種就需要先看一下AndroidMenifest中的intentfilter的配置了
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:value="android.intent.action.EDIT" />
<action android:value="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
</intent-filter>
這里面配置用到了action, data, category這些東西辱匿,那么聰明的你一定想到intent里也會(huì)有這些東西,然后一匹配不就找到接收者了嗎?
action其實(shí)就是一個(gè)意圖的字符串名稱(chēng)炫彩。上面這段intent-filter的配置文件說(shuō)明了這個(gè)Activity可以接受不同的Action匾七,當(dāng)然相應(yīng)的程序邏輯也不一樣咯,提一下那個(gè) mimeType,他是在ContentProvider里定義的,你要是自己實(shí)現(xiàn)一個(gè)ContentProvider就知道了江兢,必須指定 mimeType才能讓數(shù)據(jù)被別人使用昨忆。
總結(jié)一句,就是你調(diào)用別的界面不是直接new那個(gè)界面划址,而是通過(guò)扔出一個(gè)intent扔嵌,讓系統(tǒng)幫你去調(diào)用那個(gè)界面限府,這樣就多么松藕合啊夺颤,而且符合了生命周期被系統(tǒng)管理的原則。
想知道category都有啥胁勺,Android為你預(yù)先定制好的action都有啥等等世澜,請(qǐng)親自訪問(wèn)官方鏈接Intent
ps:想知道怎么調(diào)用系統(tǒng)應(yīng)用程序的同學(xué),可以仔細(xì)看一下你的logcat署穗,每次運(yùn)行一個(gè)程序的時(shí)候是不是有一些信息比如:
Starting activity: Intent { action=android.intent.action.MAINcategories={android.intent.category.LAUNCHER} flags=0x10200000comp={com.android.camera/com.android.camera.GalleryPicker} } , 再對(duì)照一下Intent的一些set方法寥裂,就知道怎么調(diào)用咯,希望你喜歡:)