Khóa học lập trình Android cơ bản

Serial tutorial hướng dẫn lập trình Android cơ bản

Cách debug cơ bản với Android Studio Cách debug cơ bản với Android Studio Cách debug cơ bản với Android Studio Cách debug cơ bản với Android Studio Cách debug cơ bản với Android Studio 4.7/5 (68 reviews)

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

Đã đăng 2016-09-13 02:25:26 bởi Kteam
1 bình luận 23310 lượt xem
Cách debug cơ bản với Android Studio 4.7 /5 stars (5 reviews)
 

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 Kteam  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:

 Kteam

(Ả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).

 

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  Kteam:

  • 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:

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:

 

Kteam


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:

Kteam

  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ó.

Kteam

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à HybridNative. 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);
    }
}

 

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:

 

 Kteam

 


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à):

 Kteam

 

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

 

Kteam

 

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:

 

 Kteam

 

Kteam

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)

 

Kteam

 

  1. 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 Kteam. Còn nếu chưa chạy thì chạy app ở chế độ debug bằng nút Kteam

 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). 

  • Để 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ó.

 

Kteam

 

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

 

Kteam

 

  • Để 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 Kteam 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 Kteam hoặc phím F5.
  • Để chạy code lại như bình thường, nhấn nút Resume Program Kteam 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:
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:
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 Kteam  và…

 

Kteam

 

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:

 

Kteam

 

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.

Kteam

 

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ó”. 


Tài liệu 

Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Cách debug cơ bản với Android Studio dưới dạng file PDF trong link bên dưới.

Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com

Đừng quên like hoặc +1 Google để ủng hộ Kteam và tác giả nhé! 


Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần BÌNH LUẬN bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng. 

 

Chia sẻ:
Thảo luận Hỏi và đáp Báo lỗi bài viết
Hủy bỏ   hoặc  
Cách debug cơ bản với Android Studio
vyduong244 2017-04-25 11:02:12

có thể thêm bài giảng về content provider được không ạ

0 bình chọn
Reply
Hủy bỏ   hoặc  
Hủy bỏ   hoặc  

Chiến dịch

Kteam - Howkteam Free Education