Xử lý bất đồng bộ trong lập trình Android cơ bản

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

0.0 (0 đánh giá)
Tạo bởi HowKteam Cập nhật lần cuối 5 năm trước 60.666 lượt xem 2 bình luận
Tác giả/Dịch giả: HowKteam
Học nhanh

Danh sách bài học

01. Giới thiệu lập trình Android và cài đặt môi trường 02. Các chức năng cơ bản của Android Studio 03. Cài đặt máy ảo Android - Có thể bạn chưa biết 04. Cách debug cơ bản với Android Studio 05. Các thành phần giao diện (UI) cơ bản 06. Intent & Manifest trong Lập trình Android 07. Vòng đời của Activity trong Android 08. Fragment và cơ chế BackStack 09. Material Design và Coding Convention 10. ListView và Custom Adapter 11. RecyclerView và ViewHolder trong Android Studio 12. Giao diện trượt ngang với ViewPager và Tab trong Android cơ bản 13. Animation và Transition trong lập trình Android cơ bản 14. Xử lý bất đồng bộ trong lập trình Android cơ bản 15. JSON và web API trong lập trình Android cơ bản 16. Permission trong Android 17. Xử lý nội dung đa phương tiện 18. Lưu trữ dữ liệu với SharedPreferences 19. Lưu trữ dữ liệu với SQLite 20. Lưu trữ dữ liệu với SQLite (Thực hành) 21. Thực hành SQLite với Sugar ORM 22. Tích hợp mạng xã hội - Tạo app Facebook 23. Tích hợp mạng xã hội - Login với Facebook 24. Tích hợp mạng xã hội vào ứng dụng Android (Google) 25. Tích hợp mạng xã hội vào ứng dụng Android (Google) - Phần 2 26. Google Cloud Messaging và Push Notification trong Android - Phần 1 27. Google Cloud Messaging và Push Notification trong Android - Phần 2

Xử lý bất đồng bộ trong lập trình Android cơ bản

Dẫn nhập

Ở các bài học trước, chúng ta đã cùng nhau tìm hiểu về ANIMATION & CÁC HIỆU ỨNG ĐƠN GIẢN TRONG ANDROID. Tiếp theo ở bài học này chúng ta sẽ đề cập đến một khía cạnh quan trọng khác trong lập trình Android, đó là xử lý bất đồng bộ. Bài tiếp sau nữa cũng sẽ liên quan nên các bạn hãy chú ý kỹ nhé!


Nội dung

Để đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về các phần:

Trong bài học này, chúng ta sẽ cùng tìm hiểu các vấn đề:

  • ANR.
  • Làm quen với lỗi thao tác mạng phổ biến.
  • Làm ví dụ xử lý download thông tin trên mạng và hiển thị về máy.

ANR

ANR là viết tắt của Application Not Responding (Ứng dụng không phản hồi).

Nếu đã từng sử dụng máy Android chắc hẳn bạn cũng đã ít nhất một lần gặp phải cái gì đó tương tự thế này:

Xử lý bất đồng bộ trong lập trình Android cơ bản

Nguyên nhân có thể do rất nhiều: Lỗi null, các exception được bắn ra nhưng không xử lý,… Hoặc là:

  • Không có phản hồi cho các sự kiện xuất / nhập thông tin (ghi dữ liệu vào bộ nhớ, nhập văn bản,…). Nói đơn giản là TREO máy.
  • Broadcast Receiver không hoàn thành trong vòng 10 giây.
  • Với các máy Androdi 3.1 về trước: Thao tác liên quan đến mạng quá 5 giây. Sau phiên bản 3.1 thì Google đã cấm tiệt thao tác mạng trên Main Thread.

Về cơ bản là như vậy. Tuy nhiên, hẳn các bạn sẽ tự hỏi…


Main Thread và Worker Thread là gì?

Mình đã giới thiệu ở bài đầu tiên, Android là hệ điều hành đa tiến trình, đa luồng. Các ứng dụng Android cũng có thể sử dụng được nhiều thread (luồng) tài nguyên hệ thống.

Tuy nhiên các thành phần liên quan đến giao diện người dùng đều được nhét chung vào một thread chính, gọi là UI Thread (hay Main Thread).

Các thao tác xử lý nặng hầu hết đều bị cấm thực thi trên Main Thread do sẽ gây ra trải nghiệm xấu cho người dùng (bấm nút mãi không lên, chạy mãi cứ treo là hỏng rồi, người ta sẽ xóa app ngay). Do đó chúng ta cần đưa các tác vụ này vào một Thread khác, gọi là Worker Thread.

Xử lý bất đồng bộ trong lập trình Android cơ bản

Và sau đó là cập nhật vào Main Thread. Cách làm này được gọi là thao tác xử lý bất đồng bộ (Asynchronous).

Trăm nghe không bằng một thấy, chúng ta sẽ làm thử ví dụ nho nhỏ. Là download thông tin dạng String từ một site bất kỳ, sau đó in ra màn hình Android, từ trên Main Thread lẫn Worker Thread xem chúng thực sự ra sao nhé.


ANR với thao tác mạng trên Main Thread.

Bước 1: Như mọi khi, chúng ta tạo một project mới với tên là AsyncExample với API là 13 và loại Activity là Empty Activity.

Xử lý bất đồng bộ trong lập trình Android cơ bản

Bước 2: Để cho đơn giản, dữ liệu của chúng ta sẽ lấy từ trang icanhazip.com. Vào trang này các bạn sẽ thấy địa chỉ IP của mình hiện ra. Và chúng ta sẽ đặt một TextView cho hiển thị địa chỉ này lên Activity.

Activity_main.xml

Bước 3: Trong MainActivity.java, chúng ta sẽ viết một hàm đơn giản, download thông tin từ icanhazip về và đổ vào TextView, tên hàm là testNetwork():

MainActivity.java

Nhớ đặt Permission Internet trong file AndroidManifest.xml

Và tất nhiên là chương trình sẽ bị crash rồi, do hàm testNetwork được gọi ngay trong UI Thread mà:

Xử lý bất đồng bộ trong lập trình Android cơ bản

Và khi nhìn vào log, bạn sẽ thấy NetworkOnMainThreadException:

Xử lý bất đồng bộ trong lập trình Android cơ bản

Vậy phải làm sao đây?


AsyncTask

Nói về xử lý bất đồng bộ thì quả thực không đơn giản. Mình cũng thừa nhận là mình cực kỳ gà ở khoản này. Nhưng may mắn thay là Android có một cơ chế giúp đơn giản hóa quá trình xử lý bất đồng bộ hiệu quả, phù hợp với ứng dụng nhỏ.

Đó chính là AsyncTask.

Bước 1: Chúng ta tạo một class mới, extends từ lớp AsyncTask, tạm gọi là AsyncTaskNetwork và nó có dạng ban đầu như sau:

AsyncTaskNetwork.java

Vào menu Code > Override Methods để tạo các method cần thiết. Thật ra chỉ cần doInBackground nhưng theo mình, nên tạo method theo thứ tự sau: onPreExecute, doInBackground onPostExecute:

Và nó có dạng như này:

AsyncTaskNetwork.java

Phần này tương đối khó hiểu. Các bạn lưu ý nhé: Chúng ta có 3 phần:

  • onPreExecute: Tác vụ này vẫn chạy ở UI Thread, nó sẽ chạy trước khi bắt đầu tác vụ bất kỳ nào đó trong doInBackground. Thích hợp nhất là đặt ở đây một ProgressDialog (một thông báo nhỏ quay quay) để cho người dùng biết là đang có tác vụ xử lý.
  • doInBackground: Đây chính là cái chúng ta cần. Các thao tác về mạng sẽ được đặt vô đây. doInBackground là task chạy trên Worker Thread.
  • onPostExecute: Tác vụ này chạy ở UI Thread, chúng ta sẽ cho dừng ProgressDialog ở đây, đồng thời lấy dữ liệu từ doInBackground về sau khi xử lý.

Các bạn có để ý đến các chỗ bôi màu chữ không? Đó chính là:

  • String: Đây là kiểu dữ liệu được truyền vào doInBackground.
  • Void: Đây là kiểu dữ liệu mà ta truyền vào một hàm đặc biệt có tên publishProgress(). Hàm này có sẵn trong lớp AsyncTask nhưng chúng ta không sử dụng đến. Nó dùng để cập nhật xem tác vụ đã chạy đến đâu rồi.
  • Boolean: Kiểu dữ liệu trả về sau khi hoàn thành AsyncTask. Ở đây mình đặt Boolean để thông báo: Tác vụ xử lý mạng có thành công hay không.

Và chúng ta có class AsyncTask hoàn chỉnh như thế này, để ý kỹ chỗ string[0]:

Quay lại MainActivity. Cách áp dụng AsyncTask rất đơn giản như sau, chú ý phần tham số của execute:

Đó, 2 phần tham số mình đã đánh dấu tô đậm màu vàng. Cái địa chỉ kia chính là tham số thứ nhất trong mảng string… của AsyncTask (phần tử 0). Bạn có thể truyền vào bao nhiêu tham số cũng được, nhưng phải cùng kiểu và xử lý chu đáo.

Chạy app, và chúng ta có được:

Xử lý bất đồng bộ trong lập trình Android cơ bản

Lưu ý là IP trên là của mình, của các bạn có thể khác.


Kết luận

Qua bài này chúng ta đã nắm được AsyncTask là gì, cơ chế bắt buộc xử lý tác vụ mạng trên Worker Thread của Android.

Chúng ta sẽ tìm hiểu sâu hơn về thao tác với mạng bằng Moshi và thư viện OkHttp qua bài JSON & WEB API TRONG LẬP TRINH ANDROID 

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 xuống

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 Xử lý bất đồng bộ trong lập trình Android cơ bản 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 likeshare để ủ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ê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.

Tác giả/Dịch giả

Khóa học

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

Đánh giá

0.0
0 đánh giá
Đánh giá
5
4
3
2
1

Bình luận

Để bình luận, bạn cần đăng nhập bằng tài khoản Howkteam.

Đăng nhập
tranc1710 đã bình luận 7 năm trước

anh ơi cho em hỏi, em có thể viết hàm getResult từ Api trong doInBackground được không anh?

phanvanson.info đã bình luận 7 năm trước

Lúc đầu Admin tạo class là 

public class AsinctaskNetWork extends AsyncTask<String, Void, String>

sau đó copy code vào lại là 

public class AsinctaskNetWork extends AsyncTask<String, Void, String>

làm em hoang mang quá xem đi xem lại mới biết khác nhau chỗ đó bảo không hiểu tại sao code mình lại khác code Admin 

Không có video.