Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> AndroidStudio應用調試技巧(上)

AndroidStudio應用調試技巧(上)

編輯:關於Android編程

前言

安卓開發的過程中,需要對開發的程序進行調試。谷歌官方和非官方,提供了很多幫助我們調試代碼的工具和方法。有的使用起來很簡單,有的則功能強大,很少有機會接觸。因此,我們打算由淺入深的向同學們介紹,知道針對不同的場景,使用合適的工具。

本文針對的讀者是:

對安卓程序調試需要指導的新手; 對程序調試沒有太多經驗的開發者;

在開始以前,假設各位已經做好了如下准備:

已經在搭建好了安卓軟件開發平台 一部安卓系統設備(手機或平板電腦); 一根連接電腦和安卓設備的數據線(通常是micro usb數據線); 半天時間。 耐心與求知欲。

本文將介紹到:

斷點調試; 輸出log調試; Android Device Monitor初步使用 ADB工具 wifi連接設備調試;

第1節 動態調試與靜態調試

安卓系統上調試程序,主要通過兩種形式:
1. 靜態調試:程序在運行到某一個狀態的時候,讓它暫停,用工具查看程序此時的運行信息,比如某個變量的數值;查看完成後,讓程序繼續運行,恢復到正常的工作。
2. 動態調試:在程序中,添加日志信息(log),在程序運行的時候,將log指定的信息輸出到調試的電腦上。整個過程不會打斷程序的運行。

不管哪種調試方式,都需要手機與調試的電腦通過數據線相連,借此傳遞調試信息。

1.1 設備與電腦的連接

要在設備上進行調試,首先要打開設備的開發者選項,不同品牌的安卓設備界面雖然不盡相同,但使用方式都大同小異:

啟動安卓設備上的“設置”應用,進入“關於手機”選項卡;

連續點擊“版本號”,直到出現您現在處於開發者模式!的提示信息;

 

\

 

返回上級菜單,進入“開發者選項”,開啟調試模式,鉤上USB調試;

\

將手機和電腦用USB數據線連接起來。

在Windows系統,需要為連接上的設備安裝ADB驅動:

下載ADB的Windows驅動到電腦本地; 在“我的電腦”上點鼠標右鍵,選擇“管理”,打開“設備管理器”,可以看到沒有安裝驅動的設備;

為它更新驅動,選擇“浏覽計算機查找”,

 

\

 

指定下載的ADB驅動目錄位置,點擊確定後,驅動很快就安裝成功了。

點擊Android Studio的Android Monitor窗口,就能看到這個連接上的設備了,這個窗口還輸出了手機端打印的運行信息。

\

1.2 部署應用

將應用程序通過Android Studio運行到設備上有兩個方式:run appdebug app

\

debug app可以設置斷點,進行代碼的靜態調試;而run app不能設置斷點,不能對代碼進行靜態調試。這兩種方式可以通過菜單項啟動,也可以通過快捷鍵開始。

點擊菜單欄中的綠色的小三角,就是run app

\

或者使用debug app的快捷按鍵shift+F10

在選定的設備上雙擊,

\

此時就可以在設備上看到,我們的程序運行起來了。

\

1.3 靜態調試方法

靜態調試就是凍結應用運行的狀態,仿佛時間停止了一般,然後我們逐一觀察此時程序的各個參數是否符合我們的預期。這種調試方法適用於對時間不敏感的程序。也就是說被調試的程序線程不需要依賴別的線程,即使暫時停止工作也不會影響別的工作線程或者受別的工作線程影響。

在希望代碼暫停運行的地方打斷點——在代碼前點擊一下,出現一個紅色的圓點,如果想取消,再點擊一次即可。

\

debug run的方式部署程序。當程序運行到這段代碼的這個位置時,程序將停止下來,切換到Debug窗口。這時,我們就可以觀察各個參數了。例如下圖右半區域就列出了停止時,各個變量的值;左邊區域展示了當時函數到調用棧(誰調用的這個函數)情況。我們可以逐一分析,詳細觀察,看這些值是否符合我們的預期。

\

下面的功能,將指定程序暫停後,執行下一步的走向。這些都是斷點調試經常使用到的、由我們控制程序運行步驟的功能,所以盡量記住它們對應的快捷方式;

\

Step Over:執行完成當前斷點停留處的代碼,然後停在下一行待執行的代碼處。

void fun1()
{
    int a = 0;
    fun2(); //正等待執行的代碼
    a++;    //下一步待執行的代碼
}

void fun2()
{
    int b = 0;
    b++;
}

Step Into:如果當前斷點執行處是一個函數,那麼執行Step Into後,進入到該函數。

void fun1()
{
    int a = 0;
    fun2(); //正等待執行的代碼
    a++;
}

void fun2()
{
    int b = 0;  //下一步待執行的代碼
    b++;
}

Step Out:在當前斷點執行處執行Step Out後,返回到調用該函數的地方等待執行。

void fun1()
{
    int a = 0;
    fun2(); //下一步待執行的代碼
    a++;
}

void fun2()
{
    int b = 0;  //正等待執行的代碼
    b++;
}

Resume Program:程序繼續往下執行,直到遇到下一個斷點。

有的調試功能帶有force,例如force step over,它們可以在這種場景下使用:當你想進入不是你寫的源代碼查看調用過程,但是使用不帶force的功能,卻沒有起作用。簡單來說就是不帶force的用來跟蹤自己寫的代碼,帶force的用來跟蹤SDK裡的源碼。

1.4 動態調試方法

對於那些和時間相關的程序(不能讓程序暫停,等你慢慢觀察),我們就不能使用靜態調試方法了,得采用動態調試,添加log的方式。

Log的中文名字叫做日志,在編程界表示程序運行過程中打印出的信息。根據log我們就知道現在程序運行到什麼地方了,log還可以攜帶程序中某些變量的信息輸出,讓我們更精准的知道程序當前運行的狀態。

1.4.1 代碼中添加log

在代碼中添加一段函數,就能通過特別的工具輸出這些log。
在Android代碼中添加log的方式如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d("TAG", "debug info: function=" + "onCreate()");
}

這裡面使用了Android提供的Log庫。

1.4.2 log的查看

添加了log信息後,將程序通過debug app部署到設備上,就能在Android Monitor工具的logcat窗口中看到對應的信息了。

\

輸出的調試信息如下:
03-22 03:22:39.778 8357-8357/com.anddle.calculator D/TAG: debug info: function=onCreate()

03-22 03:22:39.778:log產生的時間;
8357-8357:設備上運行這段代碼的進程ID(PID)和線程ID(TID);
com.anddle.calculator:設備上運行這段代碼的包名;
D:這條log的類型。我們輸出這條log使用的是Log.d(),所以就顯示D;如果使用Log.i()就顯示I,以此類推;
TAG:就是Log.d()函數的第一個參數;
debug info: function=onCreate():就是Log.d()函數的第二個參數;

Android應用開發的Log庫提供了幾種不同等級的log:Verbose Debug Info Warining Error,我們可以根據自己log的需要加不同等級的log,使用的形式為:

Log.v(“TAG”,”content is verbose”);
Log.d(“TAG”,”content is debug”);
Log.i(“TAG”,”content is info”);
Log.w(“TAG”,”content is waring”);
Log.e(“TAG”,”content is error”);

我們在應用中調試程序,通常使用d。

1.4.3 log的添加規則

在應用的開發當中,我們對log的添加有一些不成文的技巧,可以提高程序的開發效率。

在調試應用的同一個功能時,為它定義同一個TAG。例如,一個應用有網絡通信和本地文件讀取兩個大功能。那我們就可以為有網絡通信定義一個TAG叫做Network,為另一個本地文件讀取定義一個TAG叫做FileAccess。這樣當我們查看對應的log信息時,就很容易通過關鍵字把它們從log的海洋裡區分開。將TAG定義成一個字符串常量,便於對log輸出信息的修改。

static final String TAG1 = "Network";
static final String TAG2 = "FileAccess";
......
Log.d(TAG1,"這是網絡通信相關的log!");
Log.d(TAG2,"這是文件讀取的log!");

使用Debug開關控制log信息是否輸出。在調試應用的時候要添加很多log,當應用發布的時候,又要去掉這些log信息。添加或者刪除這些log,會增加很多工作。所以我們需要使用Debug開關

static final boolean DEBUG = true; //true表示打開開關,false表示關閉開關;
......
if(DEBUG)
{
    Log.d(TAG,"Debug開關打開才輸出!");
}

輸出函數的調用棧。有的時候,我們不僅關注程序執行到當前時各個變量的值是什麼,還關心這個函數是怎麼被調用到的。那麼我們可以在代碼中,添加輸出調用棧的信息:

Log.d(TAG, Log.getStackTraceString(new Throwable()));

Log.d()在調試代碼時使用,用Debug開關控制;Log.e()在出現意外而重要的錯誤情況時使用,不用Debug開關控制;Log.v() Log.i()Log.w()在需要輸出運行狀態並且不涉及暴露應用實現信息的情況時使用,不必用Debug開關控制;當然,開發者想怎麼用這些log類型就可以怎麼用,並沒有特別的約束。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved