理解Activity狠半,View,Window三者關(guān)系
這個(gè)問題真的很不好回答优烧。所以這里先來個(gè)算是比較恰當(dāng)?shù)谋扔鱽硇稳菹滤鼈兊年P(guān)系吧辱挥。Activity像一個(gè)工匠(控制單元),Window像窗戶(承載模型)修械,View像窗花(顯示視圖)LayoutInflater像剪刀把鉴,Xml配置像窗花圖紙。
1:Activity構(gòu)造的時(shí)候會(huì)初始化一個(gè)Window宏蛉,準(zhǔn)確的說是PhoneWindow遣臼。
2:這個(gè)PhoneWindow有一個(gè)“ViewRoot”,這個(gè)“ViewRoot”是一個(gè)View或者說ViewGroup拾并,是最初始的根視圖揍堰。
3:“ViewRoot”通過addView方法來一個(gè)個(gè)的添加View鹏浅。比如TextView,Button等
4:這些View的事件監(jiān)聽屏歹,是由WindowManagerService來接受消息隐砸,并且回調(diào)Activity函數(shù)。比如onClickListener蝙眶,onKeyDown等季希。
View的繪制流程
measure過程layout過程draw過程
從此再有不愁自定義View——Android自定義view詳解
android View繪制源碼分析(上)
android View繪制源碼分析(下)
Touch事件傳遞機(jī)制
public boolean dispatchTouchEvent(MotionEventev);
//用來分派event
public boolean onInterceptTouchEvent(MotionEventev);
//用來攔截event
public boolean onTouchEvent(MotionEventev);
//用來處理event
其中Activity和View控件(TextView)擁有分派和處理事件方法,View容器(LinearLayout)具有分派幽纷,攔截式塌,處理事件方法。這里也有個(gè)比喻:領(lǐng)導(dǎo)都會(huì)把任務(wù)向下分派友浸,一旦下面的人把事情做不好峰尝,就不會(huì)再把后續(xù)的任務(wù)交給下面的人來做了,只能自己親自做尾菇,如果自己也做不了境析,就只能告訴上級(jí)不能完成任務(wù),上級(jí)又會(huì)重復(fù)他的過程派诬。另外劳淆,領(lǐng)導(dǎo)都有權(quán)利攔截任務(wù),對下級(jí)隱瞞該任務(wù)默赂,而直接自己去做沛鸵,如果做不成,也只能向上級(jí)報(bào)告不能完成任務(wù)缆八。
Handler的原理
IntentService——Handler與Service的結(jié)合
Android 開發(fā)中利用異步來優(yōu)化運(yùn)行速度和性能
深入理解ThreadLocal(一)
Binder機(jī)制原理
為什么 Android 要采用 Binder 作為 IPC 機(jī)制曲掰?
Android中的幾種動(dòng)畫
Android 動(dòng)畫,看完這些就夠了(上)
Android 動(dòng)畫,看完這些就夠了(下)
Android中跨進(jìn)程通訊的幾種方式
1:訪問其他應(yīng)用程序的Activity
如調(diào)用系統(tǒng)通話應(yīng)用
Intent callIntent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:12345678");
startActivity(callIntent);
2:Content Provider
如訪問系統(tǒng)相冊
3:廣播(Broadcast)
如顯示系統(tǒng)時(shí)間
4:AIDL服務(wù)
請描述一下Activity 生命周期。
如下圖所示奈辰。共有七個(gè)周期函數(shù)栏妖,按順序分別是: onCreate(), onStart(), onRestart(), onResume(), onPause(),onStop(), onDestroy()。
onCreate(): 創(chuàng)建Activity時(shí)調(diào)用奖恰,設(shè)置在該方法中吊趾,還以Bundle的形式提供對以前存儲(chǔ)的任何狀態(tài)的訪問。
onStart(): Activity變?yōu)樵谄聊簧蠈τ脩艨梢姇r(shí)調(diào)用瑟啃。
onResume(): Activity開始與用戶交互時(shí)調(diào)用(無論是啟動(dòng)還是重新啟動(dòng)一個(gè)活動(dòng)论泛,該方法總是被調(diào)用。
onPause(): Activity被暫陀加欤或收回cpu和其他資源時(shí)調(diào)用屁奏,該方法用戶保護(hù)活動(dòng)狀態(tài)的,也是保護(hù)現(xiàn)場错负。
onStop(): Activity被停止并轉(zhuǎn)為不可見階段及后續(xù)的生命周期事件時(shí)調(diào)用坟瓢。
onRestart(): Activity被重新啟動(dòng)時(shí)調(diào)用勇边。該活動(dòng)仍然在棧中,而不是啟動(dòng)新的Activity折联。
1粥诫、完整生命周期: 即從一個(gè)Activity從出現(xiàn)到消失,對應(yīng)的周期方法是從onCreate()到onDestroy()崭庸。
2、可見生命周期: 當(dāng)Activity處于可以用戶看見的狀態(tài)谊囚,但不一定能與用戶交互時(shí)怕享,將多次執(zhí)行從onStart()到onStop()。
3镰踏、前景生命周期: 當(dāng)Activity處于Activity棧最頂端函筋,能夠與其他用戶進(jìn)行交互時(shí),將多次執(zhí)行從onResume()到onPause()奠伪。
兩個(gè)Activity之間跳轉(zhuǎn)時(shí)必然會(huì)執(zhí)行的是哪幾個(gè)方法跌帐。
兩個(gè)Activity之間跳轉(zhuǎn)必然會(huì)執(zhí)行的是下面幾個(gè)方法。
onCreate()//在Activity生命周期開始時(shí)調(diào)用绊率。
onRestoreInstanceState()//用來恢復(fù)UI狀態(tài)谨敛。
onRestart()//當(dāng)Activity重新啟動(dòng)時(shí)調(diào)用。
onStart()//當(dāng)Activity對用戶即將可見時(shí)調(diào)用滤否。
onResume()//當(dāng)Activity與用戶交互時(shí)脸狸,繪制界面。
onSaveInstanceState()//即將移出棧頂保留UI狀態(tài)時(shí)調(diào)用藐俺。
onPause()//暫停當(dāng)前活動(dòng)Activity炊甲,提交持久數(shù)據(jù)的改變,停止動(dòng)畫或其他占用GPU資源的東西欲芹,由于下一個(gè)Activity在這個(gè)方法返回之前不會(huì)resume卿啡,所以這個(gè)方法的代碼執(zhí)行要快。
onStop()//Activity不再可見時(shí)調(diào)用菱父。
onDestroy()//Activity銷毀棧時(shí)被調(diào)用的最后一個(gè)方法颈娜。
兩個(gè)Activity之間怎么傳遞數(shù)據(jù)?
可以在Intent對象中利用Extra來傳遞存儲(chǔ)數(shù)據(jù)滞伟。
在Intent的對象請求中揭鳞,使用putExtra(“鍵值對的名字”,”鍵值對的值”)梆奈;在另外一個(gè)Activity中將Intent中的請求數(shù)據(jù)取出來:
Intent intent = getIntent();
String value = intent.getStringExtra(“testIntent”);
Activity怎么和service綁定野崇,怎么在activity中啟動(dòng)自己對應(yīng)的service?
1亩钟、activity能進(jìn)行綁定得益于Serviece的接口乓梨。為了支持Service的綁定鳖轰,實(shí)現(xiàn)onBind方法。
2扶镀、Service和Activity的連接可以用ServiceConnection來實(shí)現(xiàn)蕴侣。需要實(shí)現(xiàn)一個(gè)新的ServiceConnection,重現(xiàn)onServiceConnected和OnServiceDisconnected方法臭觉,一旦連接建立昆雀,就能得到Service實(shí)例的引用。
3蝠筑、執(zhí)行綁定狞膘,調(diào)用bindService方法,傳入一個(gè)選擇了要綁定的Service的Intent(顯示或隱式)和一個(gè)你實(shí)現(xiàn)了的ServiceConnection的實(shí)例
什么是Service以及描述下它的生命周期什乙。Service有哪些啟動(dòng)方法挽封,有什么區(qū)別,怎樣停用Service臣镣?
Android Service是運(yùn)行在后臺(tái)的代碼辅愿,不能與用戶交互,可以運(yùn)行在自己的進(jìn)程忆某,也可以運(yùn)行在其他應(yīng)用程序進(jìn)程的上下文里点待。需要通過某一個(gè)Activity或者Context對象來調(diào)用。Service有兩個(gè)啟動(dòng)方法褒繁,分別是Context.startService()和Context.bindService()亦鳞。如果在Service執(zhí)行耗時(shí)的操作需要啟動(dòng)一個(gè)新線程來執(zhí)行。
Android Service只繼承了onCreate(), onStart(),onDestroy()三個(gè)方法棒坏,當(dāng)我們第一次啟動(dòng)Service時(shí)燕差,先后調(diào)用onCreate(), onStart()這兩個(gè)方法,當(dāng)停止Service時(shí)坝冕,則執(zhí)行onDestroy()方法時(shí)徒探。如果Service已經(jīng)啟動(dòng)了,當(dāng)我們再次啟動(dòng)Service時(shí)喂窟,不會(huì)再執(zhí)行onCreate()方法测暗,而是直接執(zhí)行onStart()方法。
什么時(shí)候使用Service磨澡?
比如播放多媒體的時(shí)候碗啄,用戶啟動(dòng)了其他Activity,這個(gè)時(shí)候程序要在后臺(tái)繼續(xù)播放稳摄,比如檢測SD卡上文件的變化稚字,再或者在后臺(tái)記錄你的地理信息位置的改變等等。
請描述一下Intent 和 Intent Filter。
Intent在Android中被翻譯為”意圖”胆描,他是三種應(yīng)用程序基本組件-Activity瘫想,Service和broadcast receiver之間相互激活的手段。在調(diào)用Intent名稱時(shí)使用ComponentName也就是類的全名時(shí)為顯示調(diào)用昌讲。這種方式一般用于應(yīng)用程序的內(nèi)部調(diào)用国夜,因?yàn)槟悴灰欢〞?huì)知道別人寫的類的全名。而Intent Filter是指意圖過濾短绸,不出現(xiàn)在代碼中,而是出現(xiàn)在android Manifest文件中礼搁,以<intent-filter>的形式。(有一個(gè)例外是broadcast receiver的intentfilter是使用Context.registerReceiver()來動(dòng)態(tài)設(shè)定的扎运,其中intent filter也是在代碼中創(chuàng)建的)
一個(gè)intent有action瑟曲,data,category等字段豪治。一個(gè)隱式intent為了能夠被某個(gè)intent filter接收洞拨,必須通過3個(gè)[測試](http://lib.csdn.net/base/softwaretest),一個(gè)intent為了被某個(gè)組件接收负拟,則必須通過它所有的intent filter中的一個(gè)掩浙。
Intent傳遞數(shù)據(jù)時(shí)花吟,可以傳遞哪些類型數(shù)據(jù)?
intent間傳送數(shù)據(jù)一般有兩種常用的方法: 1厨姚、extra 2衅澈、data。
extra可以用Intent.putExtra放入數(shù)據(jù)拭抬。新啟動(dòng)的Activity可用Intent.getExtras取出Bundle部默,然后用Bundles.getLong,getInt,getBoolean,getString等函數(shù)來取放進(jìn)去的值。
Data則是傳輸url造虎。url可以是指我們熟悉的http傅蹂,ftp等網(wǎng)絡(luò)地址,也可以指content來指向ContentProvider提供的資源累奈。Intent.setData可以放入數(shù)據(jù)贬派,Intent.getData可以取出數(shù)據(jù)急但。
請描述一下BroadcastReceiver。
Broadcast Receiver用于接收并處理廣播通知(broadcast announcements)搞乏。多數(shù)的廣播是系統(tǒng)發(fā)起的波桩,如地域變換、電量不足请敦、來電短信等镐躲。程序也可以播放一個(gè)廣播。程序可以有任意數(shù)量的broadcast receivers來響應(yīng)它覺得重要的通知侍筛。Broadcast receiver可以通過多種方式通知用戶: 啟動(dòng)activity萤皂、使用NotificationManager、開啟背景燈匣椰、振動(dòng)設(shè)備裆熙、播放聲音等,最典型的是在狀態(tài)欄顯示一個(gè)圖標(biāo)禽笑,這樣用戶就可以點(diǎn)它打開看通知內(nèi)容入录。通常我們的某個(gè)應(yīng)用或系統(tǒng)本身在某些事件(電池電量不足、來電短信)來臨時(shí)會(huì)廣播一個(gè)Intent出去佳镜,我們利用注冊一個(gè)broadcast
receiver來監(jiān)聽這些Intent并獲取Intent中的數(shù)據(jù)僚稿。
在manifest和代碼中如何注冊和使用 broadcast receiver 。
在android的manifest中注冊
<receiver android: name =“Receiver1”>
<intent-filter>
<!----和Intent中的action對應(yīng)--->
<actionandroid: name=“com.forrest.action.mybroadcast”/>
</intent-filter>
</receiver>
在代碼中注冊
1蟀伸、 IntentFilter filter = new IntentFilter(“com.forrest.action.mybroadcast”);//和廣播中Intent的action對應(yīng);
2蚀同、 MyBroadcastReceiver br= new MyBroadcastReceiver();
3、 registerReceiver(br, filter);
請介紹下ContentProvider是如何實(shí)現(xiàn)數(shù)據(jù)共享的啊掏。
一個(gè)程序可以通過實(shí)現(xiàn)一個(gè)Content provider的抽象接口將自己的數(shù)據(jù)完全暴露出去蠢络,而且Content provider是以類似[數(shù)據(jù)庫](http://lib.csdn.net/base/mysql)中的表的方式將自己的數(shù)據(jù)暴露。Content provider存儲(chǔ)和檢索數(shù)據(jù)迟蜜,通過它可以讓所有的應(yīng)用程序訪問到谢肾,這也是應(yīng)用程序之間唯一共享數(shù)據(jù)的方法。
要想使應(yīng)用程序的數(shù)據(jù)公開化小泉,可通過2種方法:創(chuàng)建一個(gè)數(shù)據(jù)自己的Content Provider或者將你的數(shù)據(jù)添加到一個(gè)已經(jīng)存在的Content Provider中芦疏,前提是有相同數(shù)據(jù)類型并且有寫入Content Provider的權(quán)限,Android提供了Content Resolverr微姊,外界的程序可以通過Content Resolver接口訪問Content Provider提供的數(shù)據(jù)酸茴。
請介紹下Android的數(shù)據(jù)存儲(chǔ)方式。
Android提供了5中存儲(chǔ)數(shù)據(jù)的方式兢交,分別是以下幾種
1薪捍、使用Shared Preferences存儲(chǔ)數(shù)據(jù),用來存儲(chǔ)key-value,pairs格式的數(shù)據(jù)酪穿,它是一個(gè)輕量級(jí)的鍵值存儲(chǔ)機(jī)制凳干,只可以存儲(chǔ)基本數(shù)據(jù)類型。
2被济、使用文件存儲(chǔ)數(shù)據(jù)救赐,通過FileInputStream和FileOutputStream對文件進(jìn)行操作。在Android中只磷,文件是一個(gè)應(yīng)用程序私有的经磅,一個(gè)應(yīng)用程序無法讀寫其他應(yīng)用程序的文件。
3钮追、使用SQLite數(shù)據(jù)庫存儲(chǔ)數(shù)據(jù)预厌,Android提供的一個(gè)標(biāo)準(zhǔn)數(shù)據(jù)庫,支持SQL語句元媚。
4轧叽、使用Content Provider存儲(chǔ)數(shù)據(jù),是所有應(yīng)用程序之間數(shù)據(jù)存儲(chǔ)和檢索的一個(gè)橋梁刊棕,它的作用就是使得各個(gè)應(yīng)用程序之間實(shí)現(xiàn)數(shù)據(jù)共享犹芹。它是一個(gè)特殊的存儲(chǔ)數(shù)據(jù)的類型,它提供了一套標(biāo)準(zhǔn)的接口用來獲取數(shù)據(jù)鞠绰,操作數(shù)據(jù)。系統(tǒng)也提供了音頻飒焦、視頻蜈膨、圖像和個(gè)人信息等幾個(gè)常用的Content Provider。如果你想公開自己的私有數(shù)據(jù)牺荠,可以創(chuàng)建自己的Content Provider類翁巍,或者當(dāng)你對這些數(shù)據(jù)擁有控制寫入的權(quán)限時(shí),將這些數(shù)據(jù)添加到Content Provider中實(shí)現(xiàn)共享休雌。外部訪問通過Content Resolver去訪問并操作這些被暴露的數(shù)據(jù)灶壶。
5、使用網(wǎng)絡(luò)存儲(chǔ)數(shù)據(jù)
談?wù)刄I中杈曲, Padding和Margin有什么區(qū)別驰凛?
Padding是控件的內(nèi)容相對控件的邊緣的邊距,而Margin是控件邊緣相對于其他控件的邊距担扑。
android本身的一些限制恰响,比如apk包大小限制,讀取大文件時(shí)的時(shí)間限
apk包大小限制不好說涌献,有的apk為100M胚宦,還是能裝到手機(jī)上。一般的apk大小為5~10M左右。讀取大文件的時(shí)間應(yīng)該是在main線程里面枢劝,時(shí)間限制為5秒左右井联。
ListView如何提高其效率?
1您旁、使用分頁加載烙常,不要一次性加載所有數(shù)據(jù)。
2被冒、復(fù)用convertView军掂。在getItemView中,判斷converView是否為空昨悼,如果不為空蝗锥,可復(fù)用。
3率触、異步加載圖片终议。Item中如果包含有webimage,那么最好異步加載葱蝗。
4穴张、快速滑動(dòng)時(shí),不顯示圖片两曼。當(dāng)快速滑動(dòng)列表(SCROLL_STATE_FLING)皂甘,item中的圖片或獲取需要消耗資源的view,可以不顯示出來悼凑;而處于其他兩種狀態(tài)(SCROLL_STATE_IDLE和SCROLL_STATE_TOUCH_SCROLL)偿枕,則將那些view顯示出來
Android程序與Java程序的區(qū)別?
談?wù)剬ndroid NDK的理解户辫。
: android NDK是一套工具渐夸,允許Android應(yīng)用開發(fā)者嵌入從C、C++源代碼編譯來的本地機(jī)器代碼到各自的應(yīng)用軟件包中渔欢。
1墓塌、 NDK是一系列工具的集合。
NDK提供了一系列的工具奥额,幫助開發(fā)者快速開發(fā)C(或C++)的動(dòng)態(tài)庫苫幢,并能自動(dòng)將so和java應(yīng)用一起打包成apk。這些工具對開發(fā)者幫助時(shí)巨大的垫挨。
NDK集成了交叉編輯器态坦,并提供了相應(yīng)的mk文件隔離CPU、平臺(tái)棒拂、API等差異伞梯,開發(fā)人員只需要簡單修改mk文件(指出“那些文件需要編譯”玫氢、“編譯特性要求”等),就可以創(chuàng)建出so谜诫。NDK可以自動(dòng)將so和Java應(yīng)用一起打包漾峡,極大的減輕了開發(fā)人員的打包工作。
2喻旷、NDK提供了一份穩(wěn)定生逸、功能有限的API頭文件聲明。這些API支持的功能非常有限且预,包含有:C標(biāo)準(zhǔn)庫(libc)槽袄、標(biāo)準(zhǔn)數(shù)學(xué)庫(libm)、壓縮庫(libz)锋谐、log庫(liblog)遍尺。
談?wù)凙ndroid的優(yōu)點(diǎn)和不足之處。
優(yōu)點(diǎn)如下所示:
1涮拗、android是開源乾戏、市場占有率大。
2三热、android能夠有豐富的硬件選擇鼓择。
3、android是一款基于[Linux](http://lib.csdn.net/base/linux)平臺(tái)的開源[操作系統(tǒng)](http://lib.csdn.net/base/operatingsystem)就漾,從而避免了專利壁壘呐能,是一款完全免費(fèi)的只能手機(jī)平臺(tái)。
4抑堡、由于android是google開發(fā)的摆出,因此能夠無縫結(jié)合Google應(yīng)用。
缺點(diǎn)如下所示:
1夷野、安全與隱私。手機(jī)與互聯(lián)網(wǎng)緊密聯(lián)系荣倾,個(gè)人隱私很難得到保守悯搔。
Android系統(tǒng)中GC什么情況下會(huì)出現(xiàn)內(nèi)存泄露呢?
導(dǎo)致內(nèi)存泄露主要的原因是舌仍,先前申請了內(nèi)存空間而忘記了釋放妒貌。如果程序中存在無用對象的引用,那么這些對象就會(huì)駐留內(nèi)存铸豁,消耗內(nèi)存灌曙,因?yàn)闊o法讓垃圾回收器GC驗(yàn)證這些對象是否不再需要。如果存在對象的引用节芥,這個(gè)對象就被定義為“有效的活動(dòng)”在刺,同時(shí)不會(huì)被釋放逆害。要確定對象所占內(nèi)存將被回收,我們就要確認(rèn)該對象不會(huì)再被使用蚣驼。典型的做法是把對象數(shù)據(jù)成員設(shè)為null或者從集合中移除該對象魄幕。當(dāng)出現(xiàn)以下情況時(shí),會(huì)造成內(nèi)存泄露:
1颖杏、 數(shù)據(jù)庫的cursor沒有關(guān)閉纯陨。
2、 構(gòu)造adapter時(shí)留储,沒有使用緩存contentview翼抠。
3、 Bitmap對象不使用時(shí)获讳,采用recycle()釋放內(nèi)存阴颖。
4、 Activity中的對象的生命周期大于activity赔嚎。
調(diào)試方法: DDMS==>HEAPSIZE==>dataobject==>[TotalSize]
Android UI中的View如何刷新膘盖。
Android中對View的更新方式有很多種,使用時(shí)要區(qū)分不同的應(yīng)用場合尤误。要分清的是:多線程和雙緩沖侠畔。
1、不使用多線程和雙緩沖
這種情況最簡單损晤,一般只希望View在發(fā)生改變時(shí)對UI進(jìn)行重繪软棺。你只需要Activity中顯式調(diào)用View對象中的invalidate()方法即可。系統(tǒng)會(huì)自動(dòng)調(diào)用View的onDraw()方法尤勋。
2喘落、使用多線程和不使用雙緩沖
這種情況下需要開啟新的線程,新開的線程就不好訪問View對象了最冰。強(qiáng)行訪問的話會(huì)報(bào)錯(cuò):android.view.ViewRoot$ CalledFromWrongThreadException: only theoriginal thread that created a view hierarchy can touch its views瘦棋。
這時(shí)候你需要?jiǎng)?chuàng)建一個(gè)繼承了android.os.handler的子類,并重寫handleMessage方法暖哨。Android.os.Handle是能發(fā)送和處理消息的赌朋,你需要在Activity中發(fā)出更新UI的消息,然后再你的Handler(可以使用匿名內(nèi)部類)中處理消息(因?yàn)槟涿麅?nèi)部類可以訪問父類變量沛慢,你可以直接調(diào)用View對象中的invalidate()方法。也就是說:在新線程中創(chuàng)建并發(fā)送一個(gè)Message团甲,然后在主線程中捕獲、處理該消息黍聂。
3身腻、使用多線程和雙緩沖
Android的SurfaceView是View的子類圾另,她同時(shí)也實(shí)現(xiàn)了雙緩沖霸株。你可以定義一個(gè)她的子類并實(shí)現(xiàn)Surfaceholder.Callback接口乖订。由于SurfaceHolder.Callback接口拖刃,新線程就不要android.os.Handler幫忙了庐扫。SurfaceHolder中l(wèi)ockCanvas()方法可以鎖定畫布蒋搜,繪制完新的圖像后調(diào)用unlockCanvasand Post解鎖荤胁。