前言
從軟件測試最終目的發(fā)現(xiàn)問題缺陷來看刁赦,F(xiàn)indyou比較認同一個觀念初橘,測試的能力大致可以劃分成三個能力層次:發(fā)現(xiàn)問題潮梯、定位問題靡羡、預(yù)防問題贱鄙。有機會探討一下這個分類扼劈。
發(fā)現(xiàn)問題各種方式方法,比如邊界值蝌矛,如何有效提高發(fā)現(xiàn)問題的效率道批?比如APP前后臺切換數(shù)據(jù)為什么容易丟失?什么情況下容易產(chǎn)生OOM?
定位問題要求測試綜合能力強入撒,你比如業(yè)務(wù)熟悉隆豹、代碼熟悉、平臺(比如Linux系統(tǒng)茅逮、Android系統(tǒng))熟悉等均有很強的要求璃赡。比如上文的栗子,APP前后臺切換界面錄入數(shù)據(jù)丟失献雅,能否通過日志碉考、代碼、系統(tǒng)機制定位到準確的原因挺身,如何找侯谁?
這是一個日積月累的過程,今天我們先從了解Android系統(tǒng)的一些知識入門學(xué)起章钾。
1
Android 四大組件
Android系統(tǒng)有四種組件墙贱,這四種組件構(gòu)成了Android應(yīng)用的框架,然后由Intent聯(lián)系這四種組件贱傀。
Activity:直譯為活動惨撇,用來顯示Android的程序界面,一個應(yīng)用往往有多個界面府寒,所以一個應(yīng)用中會有多個Activity魁衙。
Service:服務(wù),沒有界面的后臺服務(wù)株搔,會一直運行在后臺剖淀。常被用來做數(shù)據(jù)處理,也可以做一些定時的任務(wù)邪狞。
Broadcast Receiver:廣播接收器祷蝌,在廣播機制中充當(dāng)廣播的接受者的作用,Android中充滿了各種廣播帆卓,所有需要有選擇地接收一些有用的廣播巨朦,然后處理這些廣播。
Content Provider:直譯為內(nèi)容提供者剑令,它是用在不同的應(yīng)用程序之間共享數(shù)據(jù)時糊啡,可以把一個應(yīng)用的數(shù)據(jù)提供給其他的應(yīng)用使用。
Intent:意圖吁津,描述應(yīng)用想干什么棚蓄。最重要的部分是動作和動作對應(yīng)的數(shù)據(jù)堕扶。
2
Android 系統(tǒng)架構(gòu)
應(yīng)用程序?qū)樱↗ava應(yīng)用程序):
該層提供一些核心應(yīng)用程序包,例如電子郵件梭依、短信稍算、日歷、地圖役拴、瀏覽器和聯(lián)系人管理等糊探。同時,開發(fā)者可以利用Java語言設(shè)計和編寫屬于自己的應(yīng)用程序河闰,而這些程序與那些核心應(yīng)用程序彼此平等科平、友好共處。
框架層(JAVA框架):
該層是Android應(yīng)用開發(fā)的基礎(chǔ)姜性,包括活動管理器瞪慧、窗口管理器、內(nèi)容提供者部念、視圖系統(tǒng)弃酌、包管理器、電話管理器儡炼、資源管理器矢腻、位置管理器、通知管理器和XMPP服務(wù)十個部分射赛。開發(fā)人員可以完全訪問核心應(yīng)用程序所使用的API框架。
系統(tǒng)庫和android運行時層(本地框架和JAVA運行環(huán)境):
包含一些C/C++庫奶是,這些庫能被Android系統(tǒng)中不同的組件使用楣责。Android運行時包括核心庫和Dalvik虛擬機,前者既兼容了大多數(shù)Java語言所需要調(diào)用的功能函數(shù)聂沙,又包括了Android的核心庫秆麸,后者是一種基于寄存器的java虛擬機,Dalvik虛擬機主要是完成對生命周期的管理及汉、堆棧的管理沮趣、線程的管理、安全和異常的管理以及垃圾回收等重要功能坷随。
LINUX內(nèi)核層
Android 的核心系統(tǒng)服務(wù)依賴于 Linux 2.6 內(nèi)核房铭,如安全性、內(nèi)存管理温眉、進程管理缸匪、網(wǎng)絡(luò)協(xié)議棧和驅(qū)動模型。Linux內(nèi)核也是作為硬件與軟件棧的抽象層类溢。驅(qū)動:顯示驅(qū)動凌蔬、攝像頭驅(qū)動、鍵盤驅(qū)動、WiFi驅(qū)動砂心、Audio驅(qū)動懈词、flash內(nèi)存驅(qū)動、Binder(IPC)驅(qū)動辩诞、電源管理等坎弯。
3
Activity生命周期
主要有7個方法:onCreate()、onStart()躁倒、onResume()荞怒、onPause()、onStop()秧秉、onRestart()褐桌、onDestroy()。
啟動Activity:onCreate()--->onStart()--->onResume()象迎,Activity進入運行狀態(tài)荧嵌。
Activity切入后臺:onPause()--->onStop(),進入停滯狀態(tài)砾淌±泊椋【操作】當(dāng)前Activity跳轉(zhuǎn)到新的Activity界面,或者按Home鍵回主屏汪厨。
Activity返回前臺:onRestart()--->onStart()--->onResume()赃春,再次回到運行狀態(tài)。
Activity后臺劫乱,系統(tǒng)內(nèi)存不足終止织中,再啟動:onCreate()-->onStart()--->onResume(),Activity進入運行狀態(tài)衷戈。
鎖定屏與解鎖屏幕:只會調(diào)用onPause()狭吼,而不會調(diào)用onStop方法,開屏后則調(diào)用onResume()
橫豎屏切換時 Activity 的生命周期 :此時的生命周期跟清單文件里的配置有關(guān)系殖妇。1刁笙、不設(shè)置 Activity 的 android:configChanges 時,切屏?xí)匦抡{(diào)用各個生命周期默認首先銷毀當(dāng)前 activity,然后重新加載。2谦趣、設(shè)置 Activity?
android:configChanges=”orientation|keyboardHidden|screenSize”時,切屏不會重新調(diào)用各個生命周期,只會執(zhí)行 onConfigurationChanged 方法疲吸。?通常在游戲開發(fā), 屏幕的朝向都是寫死的。
4
Service生命周期
service的生命周期前鹅,從它被創(chuàng)建開始磅氨,到它被銷毀為止,可以有兩條不同的路徑:
圖轉(zhuǎn)換為文字:
context.startService() ->onCreate()- >onStartCommand()->Service running--調(diào)用context.stopService() ->onDestroy()
context.bindService()->onCreate()->onBind()->Service running--調(diào)用>onUnbind() -> onDestroy()
通常分為兩種服務(wù):
本地服務(wù)嫡纠, Local Service 用于應(yīng)用程序內(nèi)部烦租。在Service可以調(diào)用Context.startService()啟動延赌,調(diào)用Context.stopService()結(jié)束。 在內(nèi)部可以調(diào)用Service.stopSelf() 或 Service.stopSelfResult()來自己停止叉橱。無論調(diào)用了多少次startService()挫以,都只需調(diào)用一次 stopService()來停止。
遠程服務(wù)窃祝, Remote Service 用于android系統(tǒng)內(nèi)部的應(yīng)用程序之間掐松。可以定義接口并把接口暴露出來粪小,以便其他應(yīng)用進行操作大磺。客戶端建立到服務(wù)對象的連接探膊,并通過那個連接來調(diào)用服 務(wù)杠愧。調(diào)用Context.bindService()方法建立連接,并啟動逞壁,以調(diào)用 Context.unbindService()關(guān)閉連接流济。多個客戶端可以綁定至同一個服務(wù)。如果服務(wù)此時還沒有加載腌闯,bindService()會先加 載它绳瘟。
總結(jié):
如果service是被開啟的,那么它的活動生命周期和整個生命周期一同結(jié)束姿骏。
如果service是被綁定的糖声,它們它的活動生命周期是在onUnbind()方法返回后結(jié)束。
5
Fragment生命周期
切換到該Fragment:onAttach--->onCreate--->onCreateView--->onActivityCreated--->onStart--->onResume
屏幕滅掉:onPause--->onSaveInstanceState--->onStop
屏幕解鎖:onStart--->onResume
切換到其他Fragment:onPause--->onStop--->onDestroyView
切換回本身的Fragment:onCreateView--->onActivityCreated--->onStart--->onResume
回到桌面:onPause--->onSaveInstanceState--->onStop
回到應(yīng)用:onStart--->onResume
退出應(yīng)用:onPause--->onStop--->onDestroyView--->onDestroy--->onDetach
與Activity生命周期對比:
6
Activity四種啟動模式
standard
模式啟動模式分瘦,每次激活A(yù)ctivity時都會創(chuàng)建Activity姨丈,并放入任務(wù)棧中。
singleTop
如果在任務(wù)的棧頂正好存在該Activity的實例擅腰, 就重用該實例,否者就會創(chuàng)建新的實例并放入棧頂(即使棧中已經(jīng)存在該Activity實例翁潘,只要不在棧頂趁冈,都會創(chuàng)建實例)。
singleTask
如果在棧中已經(jīng)有該Activity的實例拜马,就重用該實例(會調(diào)用實例的onNewIntent())渗勘。重用時,會讓該實例回到棧頂俩莽,因此在它上面的實例將會被移除棧旺坠。如果棧中不存在該實例,將會創(chuàng)建新的實例放入棧中扮超。?
singleInstance
在一個新棧中創(chuàng)建該Activity實例取刃,并讓多個應(yīng)用共享改棧中的該Activity實例蹋肮。一旦改模式的Activity的實例存在于某個棧中,任何應(yīng)用再激活改Activity時都會重用該棧中的實例璧疗,其效果相當(dāng)于多個應(yīng)用程序共享一個應(yīng)用坯辩,不管誰激活該Activity都會進入同一個應(yīng)用中。
模式之間的區(qū)別:
singleTop跟standard模式比較類似崩侠,singleTop跳轉(zhuǎn)的對象是位于棧頂?shù)腶ctivity(用戶所見)漆魔,程序?qū)⒉粫梢粋€新的activity 實例,而是直接跳到現(xiàn)存于棧頂?shù)哪莻€activity 實例却音,按返回鍵程序?qū)⒅苯油顺觥?/p>
singleTask 模式和singleInstance模式都是只創(chuàng)建一個實例的改抡。在這種模?
式下,無論跳轉(zhuǎn)的對象是不是位于棧頂?shù)?activity,程序都不會生成一個新的實例(當(dāng)然前提是棧里面已經(jīng)有這個實例)。這種模式相當(dāng)有用,在以后的多 activity 開發(fā)中,常會因為跳轉(zhuǎn)的關(guān)系導(dǎo)致同個頁面生成多個實例,這個在用戶體驗上始終有點不好,而如果你將對應(yīng)的 activity 聲明為singleTask 模式,這種問題將不復(fù)存在系瓢,在主頁的 Activity 很常用阿纤。
7
Manifest.xml文件
Manifest.xml文件中主要包括:
manifest:根節(jié)點,描述了package中所有的內(nèi)容八拱。
uses-permission:請求你的package正常運作所需賦予的安全許可阵赠。
permission: 聲明了安全許可來限制哪些程序能你package中的組件和功能。
instrumentation:聲明了用來測試此package或其他package指令組件的代碼肌稻。
application:包含package中application級別組件聲明的根節(jié)點清蚀。
activity:Activity是用來與用戶交互的主要工具。
receiver:IntentReceiver能使的application獲得數(shù)據(jù)的改變或者發(fā)生的操作爹谭,即使它當(dāng)前不在運行枷邪。
service:Service是能在后臺運行任意時間的組件。
provider:ContentProvider是用來管理持久化數(shù)據(jù)并發(fā)布給其他應(yīng)用程序使用的組件诺凡。
8
AIDL
在Android中东揣,每個應(yīng)用(Application)執(zhí)行在它自己的進程中,無法直接調(diào)用到其他應(yīng)用的資源腹泌,這也符合“沙箱”的理念嘶卧。但各應(yīng)用間需要交互通信,因此有了IPC(進程間通信)協(xié)議:AIDL凉袱。
實現(xiàn)步驟:
定義一個AIDL接口
為遠程服務(wù)(Service)實現(xiàn)對應(yīng)Stub
將服務(wù)“暴露”給客戶程序使用
9
FC / Crash
Force close芥吟,或者Crash
常見原因
Error: OOM(out of memory error)
Error:StackOverFlowError
RuntimeException
10
Activity Not Respone
ANR,無響應(yīng)
常見原因
1专甩、當(dāng)用戶輸入事件5s內(nèi)沒有得到響應(yīng)钟鸵,將彈出ANR對話框
2、廣播接收者的onReceive()執(zhí)行時間超過10s
基礎(chǔ)知識
1涤躲、Main線程也稱為UI線程棺耍、主線程
2、功能: 1.創(chuàng)建UI控件;2.更新UI控件狀態(tài); 3.事件處理
3种樱、限制:Main線程不建議有超過5秒的事件
解決方案
1蒙袍、所有可能的耗時操作都要在子線程()中執(zhí)行
2俊卤、常見耗時操作:I/O,網(wǎng)絡(luò)操作,SDcard左敌,數(shù)據(jù)運算
3瘾蛋、子線程更新UI:handler+massage線程間通訊