前言
前言
從軟件測試最終目的發現問題缺陷來看,Findyou比較認同一個觀念,測試的能力大致可以划分成三個能力層次:發現問題、定位問題、預防問題。有機會探討一下這個分類。
發現問題各種方式方法,比如邊界值,如何有效提高發現問題的效率?比如APP前后台切換數據為什么容易丟失?什么情況下容易產生OOM?
定位問題要求測試綜合能力強,你比如業務熟悉、代碼熟悉、平台(比如Linux系統、Android系統)熟悉等均有很強的要求。比如上文的栗子,APP前后台切換界面錄入數據丟失,能否通過日志、代碼、系統機制定位到准確的原因,如何找?
這是一個日積月累的過程,今天我們先從了解Android系統的一些知識入門學起。
Android系統有四種組件,這四種組件構成了Android應用的框架,然后由Intent聯系這四種組件。
Activity:直譯為活動,用來顯示Android的程序界面,一個應用往往有多個界面,所以一個應用中會有多個Activity。
Service:服務,沒有界面的后台服務,會一直運行在后台。常被用來做數據處理,也可以做一些定時的任務。
Broadcast Receiver:廣播接收器,在廣播機制中充當廣播的接受者的作用,Android中充滿了各種廣播,所有需要有選擇地接收一些有用的廣播,然后處理這些廣播。
Content Provider:直譯為內容提供者,它是用在不同的應用程序之間共享數據時,可以把一個應用的數據提供給其他的應用使用。
Intent: 意圖,描述應用想干什么。最重要的部分是動作和動作對應的數據。

應用程序層(Java應用程序):
該層提供一些核心應用程序包,例如電子郵件、短信、日歷、地圖、瀏覽器和聯系人管理等。同時,開發者可以利用Java語言設計和編寫屬於自己的應用程序,而這些程序與那些核心應用程序彼此平等、友好共處。
框架層(JAVA框架):
該層是Android應用開發的基礎,包括活動管理器、窗口管理器、內容提供者、視圖系統、包管理器、電話管理器、資源管理器、位置管理器、通知管理器和XMPP服務十個部分。開發人員可以完全訪問核心應用程序所使用的API框架。
系統庫和android運行時層(本地框架和JAVA運行環境):
包含一些C/C++庫,這些庫能被Android系統中不同的組件使用。Android運行時包括核心庫和Dalvik虛擬機,前者既兼容了大多數Java語言所需要調用的功能函數,又包括了Android的核心庫,后者是一種基於寄存器的java虛擬機,Dalvik虛擬機主要是完成對生命周期的管理、堆棧的管理、線程的管理、安全和異常的管理以及垃圾回收等重要功能。
LINUX內核層
Android 的核心系統服務依賴於 Linux 2.6 內核,如安全性、內存管理、進程管理、網絡協議棧和驅動模型。Linux內核也是作為硬件與軟件棧的抽象層。驅動:顯示驅動、攝像頭驅動、鍵盤驅動、WiFi驅動、Audio驅動、flash內存驅動、Binder(IPC)驅動、電源管理等。
主要有7個方法:onCreate()、onStart()、onResume()、onPause()、onStop()、onRestart()、onDestroy()。

啟動Activity: onCreate()--->onStart()--->onResume(),Activity進入運行狀態。
Activity切入后台:onPause()--->onStop(),進入停滯狀態。【操作】當前Activity跳轉到新的Activity界面,或者按Home鍵回主屏。
Activity返回前台: onRestart()--->onStart()--->onResume(),再次回到運行狀態。
Activity后台,系統內存不足終止,再啟動:onCreate()-->onStart()--->onResume(),Activity進入運行狀態。
鎖定屏與解鎖屏幕:只會調用onPause(),而不會調用onStop方法,開屏后則調用onResume()
橫豎屏切換時 Activity 的生命周期 :此時的生命周期跟清單文件里的配置有關系。1、不設置 Activity 的 android:configChanges 時,切屏會重新調用各個生命周期默認首先銷毀當前 activity,然后重新加載。2、設置 Activity
android:configChanges=”orientation|keyboardHidden|screenSize”時,切屏不會重新調用各個生命周期,只會執行 onConfigurationChanged 方法。 通常在游戲開發, 屏幕的朝向都是寫死的。
service的生命周期,從它被創建開始,到它被銷毀為止,可以有兩條不同的路徑:

圖轉換為文字:
context.startService() ->onCreate()- >onStartCommand()->Service running--調用context.stopService() ->onDestroy()
context.bindService()->onCreate()->onBind()->Service running--調用>onUnbind() -> onDestroy()
通常分為兩種服務:
本地服務, Local Service 用於應用程序內部。在Service可以調用Context.startService()啟動,調用Context.stopService()結束。 在內部可以調用Service.stopSelf() 或 Service.stopSelfResult()來自己停止。無論調用了多少次startService(),都只需調用一次 stopService()來停止。
遠程服務, Remote Service 用於android系統內部的應用程序之間。可以定義接口並把接口暴露出來,以便其他應用進行操作。客戶端建立到服務對象的連接,並通過那個連接來調用服 務。調用Context.bindService()方法建立連接,並啟動,以調用 Context.unbindService()關閉連接。多個客戶端可以綁定至同一個服務。如果服務此時還沒有加載,bindService()會先加 載它。
總結:
如果service是被開啟的,那么它的活動生命周期和整個生命周期一同結束。
如果service是被綁定的,它們它的活動生命周期是在onUnbind()方法返回后結束。
切換到該Fragment:onAttach--->onCreate--->onCreateView--->onActivityCreated--->onStart--->onResume
屏幕滅掉:onPause--->onSaveInstanceState--->onStop
屏幕解鎖:onStart--->onResume
切換到其他Fragment:onPause--->onStop--->onDestroyView
切換回本身的Fragment:onCreateView--->onActivityCreated--->onStart--->onResume
回到桌面:onPause--->onSaveInstanceState--->onStop
回到應用:onStart--->onResume
退出應用:onPause--->onStop--->onDestroyView--->onDestroy--->onDetach
與Activity生命周期對比:

standard
模式啟動模式,每次激活Activity時都會創建Activity,並放入任務棧中。
singleTop
如果在任務的棧頂正好存在該Activity的實例, 就重用該實例,否者就會創建新的實例並放入棧頂(即使棧中已經存在該Activity實例,只要不在棧頂,都會創建實例)。
singleTask
如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的onNewIntent())。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移除棧。如果棧中不存在該實例,將會創建新的實例放入棧中。
singleInstance
在一個新棧中創建該Activity實例,並讓多個應用共享改棧中的該Activity實例。一旦改模式的Activity的實例存在於某個棧中,任何應用再激活改Activity時都會重用該棧中的實例,其效果相當於多個應用程序共享一個應用,不管誰激活該Activity都會進入同一個應用中。
模式之間的區別:
singleTop跟standard模式比較類似,singleTop跳轉的對象是位於棧頂的activity(用戶所見),程序將不會生成一個新的activity 實例,而是直接跳到現存於棧頂的那個activity 實例,按返回鍵程序將直接退出。
singleTask 模式和singleInstance模式都是只創建一個實例的。在這種模
式下,無論跳轉的對象是不是位於棧頂的 activity,程序都不會生成一個新的實例(當然前提是棧里面已經有這個實例)。這種模式相當有用,在以后的多 activity 開發中,常會因為跳轉的關系導致同個頁面生成多個實例,這個在用戶體驗上始終有點不好,而如果你將對應的 activity 聲明為singleTask 模式,這種問題將不復存在,在主頁的 Activity 很常用。
Manifest.xml文件中主要包括:
manifest:根節點,描述了package中所有的內容。
uses-permission:請求你的package正常運作所需賦予的安全許可。
permission: 聲明了安全許可來限制哪些程序能你package中的組件和功能。
instrumentation:聲明了用來測試此package或其他package指令組件的代碼。
application:包含package中application級別組件聲明的根節點。
activity:Activity是用來與用戶交互的主要工具。
receiver:IntentReceiver能使的application獲得數據的改變或者發生的操作,即使它當前不在運行。
service:Service是能在后台運行任意時間的組件。
provider:ContentProvider是用來管理持久化數據並發布給其他應用程序使用的組件。
在Android中,每個應用(Application)執行在它自己的進程中,無法直接調用到其他應用的資源,這也符合“沙箱”的理念。但各應用間需要交互通信,因此有了IPC(進程間通信)協議:AIDL。
實現步驟:
定義一個AIDL接口
為遠程服務(Service)實現對應Stub
將服務“暴露”給客戶程序使用
Force close,或者Crash
常見原因
Error: OOM(out of memory error)
Error:StackOverFlowError
RuntimeException
ANR,無響應
常見原因
1、當用戶輸入事件5s內沒有得到響應,將彈出ANR對話框
2、廣播接收者的onReceive()執行時間超過10s
基礎知識
1、Main線程也稱為UI線程、主線程
2、功能: 1.創建UI控件;2.更新UI控件狀態; 3.事件處理
3、限制:Main線程不建議有超過5秒的事件
解決方案
1、所有可能的耗時操作都要在子線程()中執行
2、常見耗時操作:I/O,網絡操作,SDcard,數據運算
3、子線程更新UI:handler+massage線程間通訊
參考:
[1] http://blog.csdn.net/vfush/article/details/51481127
[2] http://www.cnblogs.com/zhujiabin/p/5714797.html
本文為原創文章,如需轉載,請在開篇顯著位置注明作者和出處(這最先發在我自己玩的訂閱號)
