如同福尔摩斯般的侦查出程序中的蛛丝马迹,找到程序的 如同福尔摩斯般的侦查出程序中的蛛丝马迹,找到程序的
如同福尔摩斯般的侦查出程序中的蛛丝马迹,找到程序的 bug bug bug bug,成为一个高手 ,成为一个高手 ,成为一个高手 ,成为一个高手! ! ! !
下面是小安在大致指导下的操作流程。1. 首先,检查了main.xml文件,仔细观察之后发现小安将EditText标签,误写成EditView
输入数字,也有可能输入汉字或者其他非数字型字符,因此在前两个输入框中添加了一 个属性,指定输入的字符必须为小数(decimal)或整数(integer),语句如下:
android:numeric="decimal"
android:numeric="integer"
另外,显示结果的那个输入框不需要用户进行操作,因此可以将其设置为不获得焦点,
语句如下:android:focusable="false"
修改后的 main.xml 文件如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::
http://www.cnblogs.com/guoshiandroid/
版权所有,请保留</LinearLayout>
2. 之后再次运行程序。结果如下图:
3. 在前两个输入框分别输入 10 和 15,点击【计算】按钮。效果如下图:
仍然有错误,但是此时界面已经没有错误,接着,开始对 Java 代码进行排错。
4. 首先为代码设置断点。断点的作用就是当调试程序的时候,程序执行到该行代码时会停 止执行,等待开发人员的处理。设置断点的方法很简单,在 Eclipse 中的某行代码左侧
(编辑器边框上)双击即可。将断点设置在 OnCreate()方法的第一行代码的位置,这 样可以观察整个执行流程。如下图的位置:
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::
http://www.cnblogs.com/guoshiandroid/
版权所有,请保留5. 设置完断点之后,可以开始调试程序。需要注意的是调试程序和运行程序的方法有所区 别。调试程序的启动方法是右击项目名,选择【Debug As】�【Android Application】。
如下图:
点击之后,观察模拟手机,显示如下界面,该界面询问用户是否进行调试,如果点击
【Force Close】,则不进行调试,也不执行程序。因此我们不要点击【Force Close】按钮,
片刻之后该提示就会自动消失。
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::
http://www.cnblogs.com/guoshiandroid/
版权所有,请保留 此时模拟器界面如下:除了标题栏之外,屏幕上没有任何内容显示。而此时在电脑下方的状态栏上 Eclipse 开发的 状态条上显示为橙色,如下图:
6. 点击查看出现什么状况,Eclipse 弹出如下提示,询问是否打开 Debug 透视图。
7. 点击【Yes】,提示框消失,弹出 Debug 视图。如下图:
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::
http://www.cnblogs.com/guoshiandroid/
版权所有,请保留8. 想要程序继续执行,可以点击标题为 Debug 的那一栏的 按钮中的 第二个按钮 ,或者使用快捷键 F6,其作用是单步跳过,执行到下一行代码。如下图:
程序执行到下一行,其下一行的背景色变化,并且 移至该行。
9. 继续点击 按钮或者快捷键 F6。点击多次,直到程序执行到一个陌生的类,在 Eclipse
中 间代 码框 上 的标 题为 , 此时 代码 已 经执 行到 了 Android 框架为我们提供的处理代码,我们不必理会,此时应点击
中的第三个按钮 或者快捷键 F7,作用是从该方法中返回。一直点击该按钮或者 F7
直到界面不发生变化为止,此时代码框上选项卡为 ,也即程序
目前在 Looper 类内停止。
在此之前模拟器屏幕没有任何变化,为上面的空界面。此时再查看模拟器,发现我们的 布局文件已经在屏幕上显示。如下图:
10. 如前,在输入框中输入数字,并点击【计算】按钮。界面无变化,进入 Eclipse 中查看。
点击 F7,直到没有变化为止。查看界面,仍然提示错误,如下图:
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::
http://www.cnblogs.com/guoshiandroid/
版权所有,请保留12. 点击 Eclipse 右上方的 按钮,之后点击【Java】,如果没有【Java】选项,选择【Other】, 之后再选择【Java】,进入 Java 视图,如下图:
13. 之前的程序我们已经测试没有错误,错误应该就在点击按钮所触发的事件的代码中,因 此我们更改断点的位置,在 onClick()方法内第一行代码处双击添加断点。在上一个 super.onCreate(savedInstanceState);这一行前面的断点双击,取消该断点。如下图:
14. 重复上面第 5 步的方式以【Debug As】的方式执行调试过程。
在屏幕中已经显示出界面,如前,在输入框中输入数字,并点击【计算】,进入 Eclipse 中查看,程序执行到了第 13 步所设的断点,如下:
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::
http://www.cnblogs.com/guoshiandroid/
版权所有,请保留16. 此时点击 中的第一个按钮 或者快捷键 F5,作用是单步跳入 该行具有的方法,即 getResult()方法内部。点击 F5 后,程序执行到 getResult()方法 内第一行,效果如下图:
17. 点击 F6,直到 指向该方法最后一行即 Return 语句时停止。
我们可以查看已经执行过的代码中的变量的值,只需将鼠标在该变量上悬浮即可弹出提示 框,如下图。
18. 另外在 Eclipse 右上角的 Variables 栏中也有已经执行过的代码行中的变量值。如下图。
19. 继续点击 F6,或者 F7。 又指向“String result = getResult(num1Str, num2Str);”
一行 。点击 F6,到 下一行 “resultEdit.setText(result);”。再 次点击 F6,进 入 类中。一直点击 F7 直到没有变化为 止。此时查看模拟器,又提示错误,点击【强制关闭】。
由于是执行到“resultEdit.setText(result);”之后出错的,现在可以定位错误就在该行。
去除其他断点,将断点设定在该行,如下图:
20. 按照第 5 步的方法,以调试方式执行程序。在模拟器界面中填入数字,点击【计算】。 进入 Eclipse 中,目前 指向“resultEdit.setText(result);”一行。选中 resultEdit 这个变量,右击鼠标,选择【Watch】,如下图:
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::
http://www.cnblogs.com/guoshiandroid/
版权所有,请保留查看右上角的 栏,栏中信息如下:
发现 resultEdit=null。说明之前没有给 resultEdit 赋值,该对象为空,在 Java 中调用空 对象的方法会发生一种常见的异常——空指针异常。这时错误已经找到,我们只需要在使用 resultEdit 对象之前为其添加赋值语句即可。点击 Debug 栏的 ,表示执行程序直到下 一个断点为止,由于已没有其他断点,程序直接执行完毕。
21. 另外,大致博士对小安说,为代码添加注释是一个良好的习惯,于是为代码添加了详细 的注释信息。
修改后的 DebugActivity.java 代码如下:
package com.sharpandroid.debug;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
public class DebugActivity extends Activity { private EditText num1Edit ;
private EditText num2Edit ; private TextView resultEdit;
private Button calButton ;
@Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//得到相关对象
num1Edit = (EditText) findViewById(R.id.num1);
num2Edit = (EditText) findViewById(R.id.num2);
// 少写的一行代码,为 resultEdit 对象赋值。
resultEdit = (TextView) findViewById(R.id.result);
calButton = (Button) findViewById(R.id.calbutton);
//为计算按钮添加单击监听器
calButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //获取加数和被加数的字符串值
String num1Str = num1Edit.getText().toString();
String num2Str = num2Edit.getText().toString();
//调用 getResult()方法计算结果
String result = getResult(num1Str, num2Str);
//将结果在 resultEdit 上显示 resultEdit.setText(result);
} });
}
//将传入的两个字符串解析成 float 类型,并求他们的和之后返回和。
public String getResult(String num1Str,String num2Str){
//将第字符串解析成 float 类型
float num1 = Float.parseFloat(num1Str);
float num2 = Float.parseFloat(num2Str);
国士工作室 电话::::15711060468 Email:Email:Email:Email:[email protected] 博客::::