AndroidStudio应用调试技巧(上)

前言

安卓开发的过程中,需要对开发的程序进行调试。谷歌官方和非官方,提供了很多帮助我们调试代码的工具和方法。有的使用起来很简单,有的则功能强大,很少有机会接触。因此,我们打算由浅入深的向同学们介绍,知道针对不同的场景,使用合适的工具。

本文针对的读者是:

  1. 对安卓程序调试需要指导的新手;
  2. 对程序调试没有太多经验的开发者;

在开始以前,假设各位已经做好了如下准备:

  • 已经在搭建好了安卓软件开发平台
  • 一部安卓系统设备(手机或平板电脑);
  • 一根连接电脑和安卓设备的数据线(通常是micro usb数据线);
  • 半天时间。
  • 耐心与求知欲。

本文将介绍到:

  1. 断点调试;
  2. 输出log调试;
  3. Android Device Monitor初步使用
  4. ADB工具
  5. wifi连接设备调试;

第1节 动态调试与静态调试

安卓系统上调试程序,主要通过两种形式:

1. 静态调试:程序在运行到某一个状态的时候,让它暂停,用工具查看程序此时的运行信息,比如某个变量的数值;查看完成后,让程序继续运行,恢复到正常的工作。

2. 动态调试:在程序中,添加日志信息(log),在程序运行的时候,将log指定的信息输出到调试的电脑上。整个过程不会打断程序的运行。

不管哪种调试方式,都需要手机与调试的电脑通过数据线相连,借此传递调试信息。

1.1 设备与电脑的连接

要在设备上进行调试,首先要打开设备的开发者选项,不同品牌的安卓设备界面虽然不尽相同,但使用方式都大同小异:

  1. 启动安卓设备上的“设置”应用,进入“关于手机”选项卡;
  2. 连续点击“版本号”,直到出现您现在处于开发者模式!的提示信息;

  3. 返回上级菜单,进入“开发者选项”,开启调试模式,钩上USB调试;



将手机和电脑用USB数据线连接起来。

在Windows系统,需要为连接上的设备安装ADB驱动:

  1. 在安豆网的资源下载下载ADB的Windows驱动到电脑本地;
  2. 在“我的电脑”上点鼠标右键,选择“管理”,打开“设备管理器”,可以看到没有安装驱动的设备;
  3. 为它更新驱动,选择“浏览计算机查找”,

  4. 指定下载的ADB驱动目录位置,点击确定后,驱动很快就安装成功了。
  5. 点击Android Studio的Android Monitor窗口,就能看到这个连接上的设备了,这个窗口还输出了手机端打印的运行信息。

1.2 部署应用

将应用程序通过Android Studio运行到设备上有两个方式:run appdebug app

debug app可以设置断点,进行代码的静态调试;而run app不能设置断点,不能对代码进行静态调试。这两种方式可以通过菜单项启动,也可以通过快捷键开始。

  1. 点击菜单栏中的绿色的小三角,就是run app

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

  2. 在选定的设备上双击,

    此时就可以在设备上看到,我们的程序运行起来了。

1.3 静态调试方法

静态调试就是冻结应用运行的状态,仿佛时间停止了一般,然后我们逐一观察此时程序的各个参数是否符合我们的预期。这种调试方法适用于对时间不敏感的程序。也就是说被调试的程序线程不需要依赖别的线程,即使暂时停止工作也不会影响别的工作线程或者受别的工作线程影响。

  1. 在希望代码暂停运行的地方打断点——在代码前点击一下,出现一个红色的圆点,如果想取消,再点击一次即可。

  2. debug run的方式部署程序。当程序运行到这段代码的这个位置时,程序将停止下来,切换到Debug窗口。这时,我们就可以观察各个参数了。例如下图右半区域就列出了停止时,各个变量的值;左边区域展示了当时函数到调用栈(谁调用的这个函数)情况。我们可以逐一分析,详细观察,看这些值是否符合我们的预期。

  3. 下面的功能,将指定程序暂停后,执行下一步的走向。这些都是断点调试经常使用到的、由我们控制程序运行步骤的功能,所以尽量记住它们对应的快捷方式;

    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的添加有一些不成文的技巧,可以提高程序的开发效率。

  1. 在调试应用的同一个功能时,为它定义同一个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!");
    
  2. 使用Debug开关控制log信息是否输出。在调试应用的时候要添加很多log,当应用发布的时候,又要去掉这些log信息。添加或者删除这些log,会增加很多工作。所以我们需要使用Debug开关
    static final boolean DEBUG = true; //true表示打开开关,false表示关闭开关;
    ......
    if(DEBUG)
    {
        Log.d(TAG,"Debug开关打开才输出!");
    }
  3. 输出函数的调用栈。有的时候,我们不仅关注程序执行到当前时各个变量的值是什么,还关心这个函数是怎么被调用到的。那么我们可以在代码中,添加输出调用栈的信息:
    Log.d(TAG, Log.getStackTraceString(new Throwable()));
  4. Log.d()在调试代码时使用,用Debug开关控制;Log.e()在出现意外而重要的错误情况时使用,不用Debug开关控制;Log.v() Log.i()Log.w()在需要输出运行状态并且不涉及暴露应用实现信息的情况时使用,不必用Debug开关控制;当然,开发者想怎么用这些log类型就可以怎么用,并没有特别的约束。
时间: 2024-10-12 06:55:37

AndroidStudio应用调试技巧(上)的相关文章

AndroidStudio应用调试技巧(下)

第2节 Android Device Monitor Android Studio的Android Device Monitor(简称ADM)是我们动态调试安卓程序时重要的帮手.它提供了很多动态调试的工具和调试方法.上一章介绍的log调试,就需要通过ADM的logcat显示调试内容:它还可以查看系统内存的占用情况,可以看到系统CPU的运行情况. ADM可以在两个地方工作: 在Android Studio集成窗口:在Android Studio下方的窗口中,点击Android Monitor,就能

TiDB之mac上搭建及调试技巧

此文目的 由于本人最近已经成为TiDB的粉丝,所以就开始各种研究TiDB的源码,研究源码这个事情,首先就需要在自己电脑上不断的调试及修改.TiDB本身的代码是非常容易编译和调试的,但是要把PD.TiKV集群同时在本机上建立起来,还是有一点难度的.好在pingcap官方提供了docker-compose搭建集群的方式,可以快速的在个人电脑上启动一个TiDB的集群.但是,我要的不只是一个集群,我还希望在我的mac上实时编译调试TiDB服务,这个TiDB服务能够和docker-compose的集群里的

Chrome 中的 JavaScript 断点设置和调试技巧

你是怎么调试 JavaScript 程序的?最原始的方法是用 alert() 在页面上打印内容,稍微改进一点的方法是用 console.log() 在 JavaScript 控制台上输出内容.嗯~,用这两种土办法确实解决了很多小型 JavaScript 脚本的调试问题.不过放着 Chrome 中功能越发强大的开发者工具不用实在太可惜了.本文主要介绍其中的 JavaScript 断点设置和调试功能,也就是其中的 Sources Panel(以前叫 Scripts).如果你精通 Eclipse 中的

一探前端开发中的JS调试技巧

前言:调试技巧,在任何一项技术研发中都可谓是必不可少的技能.掌握各种调试技巧,必定能在工作中起到事半功倍的效果.譬如,快速定位问题.降低故障概率.帮助分析逻辑错误等等.而在互联网前端开发越来越重要的今天,如何在前端开发中降低开发成本,提升工作效率,掌握前端开发调试技巧尤为重要. 本文将一一讲解各种前端JS调试技巧,也许你已经熟练掌握,那让我们一起来温习,也许有你没见过的方法,不妨一起来学习,也许你尚不知如何调试,赶紧趁此机会填补空白. 骨灰级调试大师Alert 那还是互联网刚刚起步的时代,网页前

Ganglia 调试技巧

Gmond # 检查Gmond服务是否正在运行,发出如下命令:ps aux | grep gmond 输出: root      8046  0.0  0.0 103244   844 pts/0    S+   09:38   0:00 grep gmond nobody   25759  1.8  1.0 206388 82356 ?        Ssl  Apr28 208:45 /usr/local/sbin/gmond --conf=/etc/ganglia/gmond.conf #

网页调试技巧:抓取马上跳转的页面POST信息或者页面内容

http://www.qs5.org/Post/625.html 网页调试技巧:抓取马上跳转的页面POST信息或者页面内容 2016/02/02 | 心得分享 | 0 Replies 有时候调试网页或者抓别人网页的POST包的时候. 总会遇到这样的尴尬,我们需要抓取POST提交的信息. 或者获取POST完成页面返回的代码. 但是,目标页却马上就跳转了,导致,还没来得及Esc呢,页面就已经刷新了. 这种情况,起码谷歌浏览器的F12是搞不了了... 比如下面的情况 我把密码放在 被Post页面的源码

iOS各种调试技巧豪华套餐

转载自http://www.cnblogs.com/daiweilai/p/4421340.html 目录 前言 逼优鸡 知己知彼 百战不殆 抽刀断Bug 普通操作 全局断点(Global BreakPoint) 条件断点(Condational Breakpoints) 打印的艺术 NSLog 开启僵尸对象(Enable NSZombie Objects) 进击的码农 Console(lldb 命令) Profile(instruments) Xcode视图调试 结语 前言 最近博主临近毕业季

iOS开发——调试篇&Xcode常用调试技巧

Xcode常用调试技巧 Enable NSZombie Objects(开启僵尸对象) Enable NSZombie Objects可能是整个Xcode开发环境中最有用的调试技巧.这个技巧非常非常容易追踪到重复释放的问题.该技巧会以非常简洁的方式打印指出重复释放的类和该类的内存地址. 怎么开启僵尸对象呢?首先打开“Edit Scheme”(或者通过热键?<),然后选择Diagnostics选项卡,勾选Enable NSZombie Objects选项. 现在我们可以关掉ARC来测试重复释放的问

Linux c c++ 开发调试技巧

看到一篇介绍 linux c/c++ 开发调试技巧的文章,感觉挺使用,哪来和大家分享. 通向 UNIX 天堂的 10 个阶梯Author: Arpan Sen, 高级技术人员, Systems Documentation, Inc. (SDI) 讨论几种可以帮助 C++ 开发人员节省时间的技巧和免费工具. C++ 开发人员在日常工作中通常要完成多个任务:开发新软件.调试其他人的代码.制订测试计划.为每个计划开发测试.管理衰退软件(regression suite)等等.在多种角色之间频繁转换会消