HOWKTEAM.VN - Cách debug cơ bản với Android Studio

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 12

Cách debug cơ bản với Android Studio 1|12

Bài: Cách debug cơ bản với Android Studio


Xem bài học trên website để ủng hộ Kteam: Cách debug cơ bản với Android Studio

Mọi vấn đề về lỗi website làm ảnh hưởng đến bạn hoặc thắc mắc, mong muốn khóa học mới, nhằm hỗ trợ cải thiện Website. Các bạn vui lòng phản hồi
đến Fanpage How Kteam nhé!

Dẫn nhập
Ở các bài học trước, chúng ta đã tìm hiểu CÁCH SỬ DỤNG CƠ BẢN ANDROID STUDIO , cách tạo và khởi chạy một project Android hoàn chỉnh.
Tuy nhiên ác mộng của những ai làm lập trình hẳn các bạn cũng đã biết: BUG.

Trong bài học này, chúng ta cùng tìm hiểu về Cách gỡ lỗi cơ bản (debug) chương trình bằng Android Studio, cũng như một số trường hợp lỗi
thường gặp.

Tổng quan
Cũng như nhiều IDE khác, Android Studio có cung cấp khả năng debug ứng dụng rất hiệu quả cho các ứng dụng chạy trên máy thật lẫn máy ảo.
Bạn có thể:

Chọn thiết bị để debug.


Đặt các breakpoint (điểm dừng) trong code.
Quan sát và kiểm tra các giá trị biến / biểu thức trong runtime.
Chụp ảnh màn hình ứng dụng.

Nội dung
Để bắt đầu thực hành, chúng ta cần có một project cơ bản. Mời các bạn xem lại bài viết trước: CÁC CHỨC NĂNG CƠ BẢN CỦA ANDROID
STUDIO để tạo ra project mẫu. Rất nhanh thôi!

Trường hợp 1: Ứng dụng của bạn chưa được chạy ở chế độ Debug:
Để bắt đầu debug, các bạn nhấn vào nút Debug trên thanh công cụ (khi trỏ vào sẽ có chữ “Debug ‘app’”).

Lúc này Android Studio sẽ build ứng dụng ra file APK, ký (sign) file APK bằng key debug, và cài đặt lên thiết bị của bạn. Cuối cùng, cửa sổ Debug sẽ
được mở ra:

(Ảnh minh họa cửa sổ Debug, liệt kê các tác vụ chạy ở main thread và cây đối tượng của một biến).

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 2|12

Nếu như cửa sổ Select Deployment Target hiện lên nhưng không có thiết bị nào trong danh sách sau khi bạn nhấn nút Debug :

Hãy kết nối thiết bị Android của bạn.


Tham khảo lại bài viết trước:
CÁC CHỨC NĂNG CƠ BẢN CỦA ANDROID STUDIO
Xem cách bật chức năng cho phép debug ứng dụng trên thiết bị của bạn ở Bước 4: Activity đầu tiên.

Nếu thực hiện đúng các bước thì cửa sổ Select Deployment Target sẽ hiển thị danh sách thiết bị như sau:

Trường hợp 2: Ứng dụng của bạn đã chạy (trên máy ảo/máy thật):
Trong trường hợp này, bạn có thể bắt đầu Debug bằng các bước sau:

1. Click vào nút Attach Debugger to Android Process:

1. Cửa sổ Choose Process sẽ hiện lên. Lúc này bạn sẽ chọn process tương ứng để trình Debug của Android Studio theo dõi nó.

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 3|12

Mặc định thì trình Debugger hiển thị thiết bị và process của app ở project hiện tại, cùng với các thiết bị đã được chạy hoặc kết nối với máy tính
đang làm việc.

Chọn Show all processes để hiển thị tất cả các thiết bị, các process service do app bạn đang làm tạo ra, hoặc các tiến trình của thiết bị tạo ra (nếu
nó đã được root).

Ở lựa chọn Debugger, bạn chon Auto hoặc Java. Nếu project của bạn có chứa code C++ và/hoặc code JavaScript (làm app Hybrid) thì sẽ có thêm 2
lựa chọn là Hybrid và Native. Lúc này chúng ta chỉ có Java mà thôi.

Sử dụng Log
Khác với Terminal của các ứng dụng Java thông thường. Với Android Studio chúng ta có một công cụ mới là LogCat. Về bản chất của chúng thì như
nhau, nhưng LogCat cho phép người khác viết plugin để hoạt động linh hoạt hơn, và nó là một công cụ tách rời trong Android SDK. Phần này
chúng ta cùng tìm hiểu cách sử dụng LogCat, không đề cập đến việc viết plugin.

Để sử dụng LogCat, thay vì viết System.out.println() như code Java thường thì bạn thay bằng các hàm của lớp Log.

Log giúp chúng ta hiểu được thứ tự khởi chạy của code bằng cách thu nhặt dữ liệu của hệ thống trong khi chúng ta chạy app, và cho chúng ta biết
được ứng dụng lỗi ở điểm nào.

Bước 1: Đặt Log trong code


Quay trở lại với ví dụ mà chúng ta đang thao tác (HelloWorld). Chúng ta đã có một class có tên MainActivity.java với nội dung như sau:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 4|12

Sửa lại một chút như sau:

public class MainActivity extends AppCompatActivity {

public static final String TAG = MainActivity.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Log.e(TAG, "savedInstanceState is null");
} else {
Log.e(TAG, "savedInstanceState is not null");
}

setContentView(R.layout.activity_main);
}
}

Các bạn sẽ thấy chữ Log bị bôi đỏ và có tooltip android.util.Log? Alt+Enter hiện ra như hình dưới. Bạn chưa import class Log vào nên nó hiển thị
vậy thôi. Nhấn Alt+Enter là Log sẽ được tự động import vào class MainActivity:

Bước 2: Đọc Log


Và bây giờ, chạy app (chạy - Run hoặc Debug đều được, vì chúng ta chỉ cần xem Log thôi mà):

Chạy xong, các bạn xem phần (1) Android Monitor và để ý đến dòng bôi đậm (2) như hình:

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 5|12

Vậy tức là tham số savedInstanceState là null.

Các bạn có để ý rằng: Ở đầu code trước hàm onCreate() mình có đặt một biến TAG như sau:

public static final String TAG = MainActivity.class.getSimpleName();

Và sau đó gọi biến TAG này trong phần Log.e():

Log.e(TAG, "savedInstanceState is null");

Đặt biến TAG ở đầu mỗi class như thế này rất hữu ích. Nó sẽ giúp các bạn biết được Log mình đang xem nằm ở class nào. Vì sau này khi thực hiện
những dự án lớn, những app phức tạp, sẽ có rất nhiều class / interface được tạo ra.

Cả 2 cửa sổ Android DDMS (Dalvik Debug Monitor Server) và Android Monitor (hình mà chúng ta vừa xem ở ngay bên trên) đều cung cấp Log cho
chúng ta trong quá trình app chạy.

Để chạy công cụ Android DDMS, các bạn click vào menu Tools > Android > Android Device Monitor:

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 6|12

Và theo dõi cửa sổ LogCat, các bạn cũng thấy được dòng log như trong Android Monitor đã đề cập ở đầu Bước 2: Đọc Log.

Làm việc với Breakpoint


Android Studio có cung cấp cơ chế đặt điểm dừng (Break Point) để khởi chạy một thao tác gỡ lỗi ứng dụng nào đó. Trong đó phổ biến nhất là đặt
breakpoint để dừng ứng dụng tạm thời khi một dòng code nào đó được gọi tới.

Sau khi app được dừng (pause), các bạn có thể kiểm tra thông số các biến, kiểm tra biểu thức, hoặc chạy tiếp code từng dòng một để tìm ra điểm lỗi
trong code.

Để đặt Breakpoint trong code, các bạn làm như sau:

1. Tìm dòng code muốn đặt Breakpoint, click chuột trái vào khoảng trống ở cột trái trước dòng code. Hoặc đặt nháy con trỏ chuột ở dòng code
muốn đặt Breakpoint và bấm tổ hợp phím Ctrl+F8 (hoặc Command+F8 với máy Mac)

2. Nếu app đang chạy, bạn không cần sửa thêm gì mà chỉ cần nhấn nút Attach Debugger to Android process . Còn nếu chưa chạy thì chạy
app ở chế độ debug bằng nút

Khi code chạy đến đúng điểm dừng đã đặt, Android Studio sẽ dừng ứng dụng lại (màn hình sẽ bị dừng lại – đóng băng, không thể thao tác được
gì thêm).

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 7|12

Để xem cây object cho một biến, quan sát vùng Variables và mở các mũi tên của nó.

Để phân tích biểu thức tại điểm đặt, nhấn nút Evaluate Expression

Để nhảy đến dòng code tiếp theo (mà không vào đầu phương thức), nhấn nút Step Over hoặc nút F6 trên bàn phím.
Để nhảy vào dòng đầu tiên trong một phương thức, nhấn Step Into hoặc phím F5.
Để chạy code lại như bình thường, nhấn nút Resume Program hoặc phím F8.

Ví dụ: Tiêu diệt NullPointerException


Về cơ bản thì debug trên Android là như vậy. Bây giờ chúng ta hãy thử làm một ví dụ nhỏ: Tự tạo một bug trong chính ứng dụng của mình và debug
nó. Chúng ta sẽ đặt một nút Button khai báo nhưng chưa khởi tạo (nghĩa là nó sẽ null), sau đó đặt text cho Button này.

Tất nhiên là ứng dụng sẽ báo lỗi và đóng app lại ngay, lỗi ở đây chính là NullPointerException (biến trả về giá trị rỗng) – một lỗi rất phổ biến và
cũng khiến nhiều bạn mới làm quen với lập trình ngán ngẩm.

Nhưng đừng sợ hãi! NullPointerException thật ra lại chính là lỗi dễ xử lý nhất.

Và sau đây Kteam sẽ chứng minh cho các bạn:

Phần 1: Tạo bug


Vẫn lấy code HelloWorld ở bài trước làm ví dụ. chúng ta vẫn chỉ có một class là java với nội dung sau khi chỉnh sửa ở phần Sử dụng Log –
Bước 1 như sau:

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 8|12

public class MainActivity extends AppCompatActivity {

public static final String TAG = MainActivity.class.getSimpleName();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Log.e(TAG, "savedInstanceState is null");
} else {
Log.e(TAG, "savedInstanceState is not null");
}

setContentView(R.layout.activity_main);
}
}

Chúng ta khai báo một biến Button ngay phía dưới biến TAG ở trên, và đặt null như sau:

public static final String TAG = MainActivity.class.getSimpleName();

Button button;

Cuối cùng, chúng ta đặt chữ cho Button đó như sau:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Log.e(TAG, "savedInstanceState is null");
} else {
Log.e(TAG, "savedInstanceState is not null");
}

setContentView(R.layout.activity_main);
button.setText("Hello Kteam");
}

Toàn bộ code của class java lúc này có nội dung đầy đủ như sau:

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 9|12

package com.howkteam.helloworld;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

public static final String TAG = MainActivity.class.getSimpleName();

Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Log.e(TAG, "savedInstanceState is null");
} else {
Log.e(TAG, "savedInstanceState is not null");
}

setContentView(R.layout.activity_main);
button.setText("Hello K-Team");
}
}

Chạy thử app dưới chế độ debug bằng cách nhấn nút Debug và…

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 10|12

App của chúng ta crash ngay lập tức. Đừng lo, đây là một vụ án có sắp đặt từ trước. Thủ phạm chính là chúng ta, vậy hãy tìm cách xóa sạch chứng
cứ.

Phần 2: Gỡ bug
Ngay sau khi ứng dụng lỗi thì việc ta làm đầu tiên luôn là mở Android Monitor ra kiểm tra, và lúc này chúng ta có như sau:

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 11|12

Vâng! một tràng dài những dòng Log được xuất ra. Nhưng hãy để ý phần được bôi đậm, nó có kèm link đến dòng code lỗi (ở đây là
MainActivity.java dòng số 24). Nguyên nhân lỗi được khoanh ở khung đỏ, và không gì khác ngoài NullPointerException.

Nào, cùng xóa tang chứng vật chứng. Dòng số 24 ở đây chính là dòng:

button.setText("Hello K-Team");

Lý do rất đơn giản: Chúng ta đã khai báo một Button ở đầu class nhưng chưa khởi tạo cho nó. Một Button cần nhận đầu vào ở constructor là một
Context (hoặc Activity). Bản thân MainActivity.java đã là một Activity nên chỉ cần từ khóa this là đủ. Chúng ta làm như sau:

button = new Button(this);button.setText("Hello K-Team");

Chạy lại app, và lỗi đã biến mất.

Copyright © Howkteam.com
Cách debug cơ bản với Android Studio 12|12

Tuy nhiên cái nút không hiển thị trên màn hình vì layout chưa được chỉ định “thêm” nút này vào. Vấn đề này sẽ được giải quyết ở bài sau: CÁC
THÀNH PHẦN GIAO DIỆN (UI VIEWS) CƠ BẢN, DRAWABLES VÀ XML.

Kết luận
Qua bài này chúng ta đã nắm được cách debug chương trình, biết về DDMS, Android Monitor, Android Debugger và các phím tắt để thực hiện
debug chương trình nhanh chóng. Các bạn cũng đã được làm thử một ví dụ thực tế: Debug một lỗi rất phổ biến trong lập trình Android là
NullPointerException.

Bài sau chúng ta sẽ tìm hiểu về CÁC THÀNH PHẦN GIAO DIỆN (UI) CƠ BẢN

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách –
Không ngại khó”.

Copyright © Howkteam.com

You might also like