Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Android SDK

Làm quen với Retrofit 2 HTTP Client

by
Difficulty:IntermediateLength:LongLanguages:

Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)

Final product image
What You'll Be Creating

Retrofit là gì?

Retrofit là một HTTP client type-safe cho Android và Java. Retrofit giúp dễ dàng kết nối đến một dịch vụ REST trên web bằng cách chyển đổi API thành Java Interface. Trong bài này, tôi sẽ hướng dẫn bạn cách sử dụng một trong những thư viện HTTP phổ biến nhất và được khuyến dùng nhất cho Android.

Thư viện mạnh mẽ này giúp bạn dễ dàng xử lý dữ liệu JSON hoặc XML sau đó phân tích cú pháp thành Plain Old Java Objects (POJOs). Tất cả các yêu cầu GETPOSTPUTPATCH, và DELETE đều có thể được thực thi.

Giống như hầu hết các phần mềm mã nguồn mở khác, Retrofit được xây dựng dựa trên một số thư viện mạnh mẽ và công cụ khác. Đằng sau nó, Retrofit làm cho việc sử dụng OkHttp (từ cùng một nhà phát triển) để xử lý các yêu cầu trên mạng. Ngoài ra, Retrofit không tích hợp bất kỳ một bộ chuyển đổi JSON nào để phân tích từ JSON thành các đối tượng Java. Thay vào đó nó đi kèm với các thư viện chuyển đổi JSON sau đây để xử lý điều đó:

  • Gson: com.squareup.retrofit:converter-gson
  • Jackson: com.squareup.retrofit:converter-jackson
  • Moshi: com.squareup.retrofit:converter-moshi
  • Protobuf: com.squareup.retrofit2:converter-protobuf
  • Wire: com.squareup.retrofit2:converter-wire

Và đối với XML, Retrofit hỗ trợ:

  • Simple Framework: com.squareup.retrofit2:converter-simpleframework

Vậy tại sao nên sử dụng Retrofit?

Việc phát triển thư viện HTTP type-safe của chính bạn để giao tiếp với REST API có thể thật sự là một điều khó khăn: bạn phải xử lý nhiều chức năng chẳng hạn như tạo các kết nối, lưu trữ cach, thử lại các yêu cầu thất bại, phân tích luồng phản hồi, xử lý lỗi, và nhiều hơn nữa. Retrofit, mặt khác, được hoạch định rất tốt, có tài liệu hướng dẫn và kiểm đã được kiểm thử—một thư viện đã được thử nghiệm rất nhiều trong thực tế sẽ giúp bạn tiết kiệm rất nhiều thời gian quý báu và giảm bớt căng thẳng.

Trong hướng dẫn này, tôi sẽ giải thích cách sử dụng Retrofit 2 để xử lý yêu cầu trên mạng bằng cách xây dựng một ứng dụng đơn giản để truy vấn những câu trả lời gần đây từ Stack Exchange API. Chúng ta sẽ thực hiện các yêu cầu GET bằng cách thiết lập một endpoint — /answers, nối nó vào URL cơ bản https://api.stackexchange.com/2.2/ — sau đó nhận kết quả và hiển thị chúng trong một recycler view. Tôi cũng sẽ hướng dẫn bạn cách làm thế nào để làm điều này với RxJava để dễ dàng quản lý dòng trạng thái và dữ liệu.

1. Tạo một dự án Android Studio

Mở Android Studio và tạo một dự án mới với một activity rỗng được gọi là MainActivity.

Create a new empty activity

2. Định nghĩa các phụ thuộc

Sau khi tạo một dự án mới, định nghĩa các phụ thuộc sau đây trong build.gradle của bạn. Các phụ thuộc bao gồm một recycler view, thư viện Retrofit và thư viện Gson của Google để chuyển đổi JSON sang POJO (Plain Old Java Objects) cũng như các thư viện Gson được tích hợp sẵn của Retrofit.

Đừng quên đồng bộ dự án để tải về các thư viện này.

3. Thêm Internet Permission

Để thực hiện hoạt động truy cập mạng, chúng ta cần phải bao gồm quyền INTERNET trong tập tin manifest của ứng dụng: AndroidManifest.xml.

4. Tạo ra các Model một cách tự động

Chúng ta sẽ tạo ra các Model của chúng ta một cách tự động từ dữ liệu trả về JSON của chúng ta bằng cách tận dụng một công cụ rất hữu ích: jsonschema2pojo.

Nhận dữ liệu JSON mẫu

Sao chép và dán liên kết https://api.stackexchange.com/2.2/answers?order=desc&sort=activity&site=stackoverflow vào trong trình duyệt của bạn (hoặc bạn có thể sử dụng ứng dụng Postman nếu bạn rành về công cụ đó). Sau đó nhấn Enter—điều này sẽ thực hiện một yêu cầu GET trên endpoint đã cho. Những gì bạn sẽ thấy trong dữ liệu trả về là một mảng của các đối tượng JSON. Ảnh chụp màn hình dưới đây là dữ liệu JSON trả về  bằng cách sử dụng Postman.

API response to GET request

Sao chép dữ liệu JSON trả về từ trình duyệt hoặc ứng dụng Postman của bạn.

Ánh xạ dữ liệu JSON vào Java

Bây giờ hãy truy cập vào jsonschema2pojo và dán các dữ liệu JSON trả về vào hộp nhập liệu.

Chọn Source type là JSON, Annotation style là Gson, và bỏ chọn Allow additional properties.

jsonschema2pojo interface

Sau đó nhấp vào nút Preview để tạo ra các đối tượng Java.

jsonschema2pojo output

Bạn có thể thắc mắc là các chú thích @SerializedName@Expose làm gì trong đoạn code được tạo ra này. Đừng lo, tôi sẽ giải thích tất cả!

@SerializedName cần thiết cho Gson để ánh xạ các khoá JSON với các trường dữ liệu của chúng ta. Để phù hợp với quy ước đặt tên kiểu camelCase của Java cho các thuộc tính thành viên của lớp, bạn không nên sử dụng dấu gạch dưới để tách các từ ngữ trong một biến. @SerializedName giúp chuyển đổi giữa hai cái này.

Trong ví dụ trên, chúng ta đang nói cho Gson của chúng ta biết rằng khoá JSON quota_remaining nên được ánh xạ tới trường dữ liệu quotaRemaining trong Java. Nếu cả hai giá trị này như nhau, tức là nếu khóa JSON của chúng ta là quotaRemaining giống trường dữ liệu Java, thì sau đó không cần chú thích @SerializedName trên trường dữ liệu vì Gson sẽ ánh xạ chúng một cách tự động.

Chú thích @Expose chỉ ra rằng thành viên này nên được trình bày với JSON serialization hoặc deserialization.

Nhập các Model dữ liệu vào Android Studio

Bây giờ hãy quay trở lại Android Studio. Tạo một gói (package) con mới bên trong gói chính và đặt tên là data. Bên trong gói dữ liệu mới được tạo, hãy tạo ra một gói khác và đặt tên là model. Bên trong gói model, tạo ra một lớp Java mới và đặt tên là Owner. Bây giờ sao chép lớp Owner được tạo ra bởi jsonschema2pojo và dán nó bên trong lớp Owner mà bạn đã tạo.

Thực hiện tương tự đối với lớp Item mới, được sao chép từ jsonschema2pojo.

Cuối cùng, tạo ra một lớp được gọi là SOAnswersResponse cho các câu trả lời từ StackOverflow. Bạn sẽ thấy code cho lớp này ở trong jsonschema2pojo có tên là Example. Hãy chắc chắn rằng bạn cập nhật tên lớp thành SOAnswersResponse nếu điều đó xảy ra.

5. Tạo đối tượng Retrofit

Để gởi các yêu cầu trên mạng đến một API REST với Retrofit, chúng ta cần tạo ra một đối tượng bằng cách sử dụng lớp Retrofit.Builder và cấu hình nó với một URL cơ sở.

Tạo một gói con mới bên trong gói data và đặt tên cho nó là remote. Bây giờ bên trong remote, tạo một lớp Java và đặt tên nó là RetrofitClient. Lớp này sẽ tạo ra một singleton của Retrofit. Retrofit cần một URL cơ sở để xây dựng đối tượng của nó, do đó, chúng ta sẽ truyền qua một URL khi gọi RetrofitClient.getClient (String baseUrl). URL này sau đó sẽ được sử dụng để xây dựng đối tượng ở dòng 13. Chúng ta cũng xác định bộ chuyển đổi JSON mà chúng ta cần (Gson) trong dòng số 14.

6. Tạo API Interface

Bên trong gói remote, tạo ra một interface và gọi nó là SOService. Đối tượng này chứa các phương thức mà chúng ta sẽ sử dụng để thực thi các yêu cầu HTTP như GET, POST, PUT, PATCH, và DELETE. Đối với hướng dẫn này, chúng ta sẽ thực hiện một yêu cầu GET.

Chú thích @GET định nghĩa rõ ràng rằng yêu cầu GET sẽ được thực hiện một khi phương thức được gọi. Mỗi phương pháp trong interface này phải có một chú thích HTTP cung cấp phương thức yêu cầu và URL tương đối. Có năm chú thích được tích hợp sẵn gồm: @GET, @POST, @PUT, @DELETE@HEAD.

Trong định nghĩa của phương thức thứ hai, chúng ta đã thêm một tham số truy vấn cho chúng ta để lọc dữ liệu từ máy chủ. Retrofit có chú thích @Query("key") để sử dụng thay vì thiết lập bằng tay ở trong endpoint. Giá trị khoá đại diện cho tên tham số trong URL. Nó sẽ được thêm vào URL bởi Retrofit. Ví dụ, nếu chúng ta truyền qua giá trị "android" như là đối số cho phương thức getAnswers(String tags), URL đầy đủ sẽ là:

Các tham số của các phương thức của interface có thể có các chú thích sau đây:

@Path biến thay thế cho API endpoint
@Query xác định tên khoá truy vấn với giá trị của tham số được chú thích
@Body payload cho việc gọi POST
@Header thiết lập header với giá trị của tham số được chú thích

7. Tạo các tiện ích API

Bây giờ chúng ta sẽ tạo ra một lớp tiện ích. Chúng ta sẽ đặt tên nó ApiUtils. Lớp này sẽ có URL cơ sở như là một biến tĩnh và đồng thời cung cấp interface SOService đến ứng dụng của chúng ta thông qua phương thức tĩnh getSOService().

8. Hiển thị một RecyclerView

Bởi vì các kết quả sẽ được hiển thị trong một recycler view, nên chúng ta cần một adapter. Đoạn code sau đây cho thấy các lớp AnswersAdapter.

9. Thực thi yêu cầu

Bên trong phương thức onCreate() của MainActivity, chúng ta khởi tạo một đối tượng của interface SOService (dòng số 9), recycler view và adapter. Cuối cùng, chúng ta gọi phương thức loadAnswers().

Phương thức loadAnswers() tạo một yêu cầu trên mạng bằng cách gọi enqueue(). Khi dữ liệu được trả về, Retrofit giúp chúng ta phân tích dữ liệu JSON trả về thành một danh sách các đối tượng Java. (Điều này được thực hiện bằng cách sử dụng GsonConverter.)

10. Hiểu về enqueue()

enqueue() gởi một cách không đồng bộ yêu cầu và thông báo cho ứng dụng của bạn bằng một callback khi có một dữ liệu trả về. Vì yêu cầu này là không đồng bộ, nên Retrofit xử lý nó trong một tác vụ nền vì thế giao diện người dùng không bị khoá hoặc ảnh hưởng bởi nó.

Để sử dụng enqueue(), bạn phải thực hiện hai phương thức callback:

  • onResponse()
  • onFailure()

Chỉ một trong những phương thức này sẽ được gọi để đáp ứng một yêu cầu nhất định.

  • onResponse(): được gọi khi nhận được một phản hồi HTTP. Phương thức này được gọi để cho một phản hồi có thể được xử lý một cách chính xác ngay cả khi máy chủ trả về một thông báo lỗi. Vì vậy nếu bạn nhận được một mã số trạng thái là 404 hoặc 500, thì phương thức này sẽ vẫn được gọi. Để có được mã số trạng thái để bạn xử lý các tình huống dựa trên chúng, thì bạn có thể sử dụng phương thức response.code(). Bạn cũng có thể sử dụng phương thức isSuccessful() để xác định xem mã trạng thái có ở trong khoảng 200-300 không, để xác định yêu cầu thành công.
  • onFailure(): được gọi khi một ngoại lệ (network exception) xảy ra khi đang giao tiếp với máy chủ, hoặc khi một ngoại lệ bất ngờ xảy ra thì nó sẽ xử lý yêu cầu hoặc xử lý phản hồi.

Để thực hiện một yêu cầu đồng thời, bạn có thể sử dụng phương thức execute(). Lưu ý rằng các phương thức đồng bộ trên tác vụ chính/UI sẽ chặn bất kỳ hoạt động nào của người dùng. Vì vậy, đừng thực hiện các phương thức đồng bộ trên tác vụ chính/UI của Android! Thay vào đó, chạy chúng trên một tác vụ nền.

11. Chạy thử ứng dụng

Bây giờ, bạn đã có thể chạy ứng dụng.

Sample results from StackOverflow

12. Tích hợp RxJava

Nếu bạn là một fan hâm mộ của RxJava, bạn có thể dễ dàng cài đặt Retrofit với RxJava. Trong Retrofit 1, nó đã được tích hợp mặc định, nhưng Retrofit 2 bạn cần phải bao gồm một số phụ thuộc. Retrofit đi kèm với một adapter mặc định để thực thi các đối tượng Call. Vì vậy, bạn có thể thay đổi cơ chế thực thi của Retrofit để bao gồm các RxJava bằng cách thêm CallAdapter của RxJava.

Bước 1

Thêm các phụ thuộc.

Bước 2

Thêm CallAdapter mới RxJavaCallAdapterFactory.create() khi xây dựng một đối tượng Retrofit.

Bước 3

Khi thực hiện các yêu cầu, subscriber vô danh của chúng ta phản hồi đến luồng có thể quan sát mà phát ra các sự kiện, trong trường hợp của chúng ta là SOAnswersResponse. Phương thức onNext sau đó được gọi khi subscriber của chúng ta nhận được bất kỳ sự kiện phát ra mà sau đó được truyền qua adapter của chúng ta.

Hãy xem bài viết Làm quen với ReactiveX trên Android bởi Ashraff Hathibelagal để tìm hiểu thêm về RxJava và RxAndroid.

Kết luận

Trong hướng dẫn này, bạn đã được học về Retrofit: lý do và cách bạn có thể sử dụng nó. Tôi cũng đã giải thích cách tích hợp RxJava với Retrofit. Trong bài viết tiếp theo của tôi, tôi sẽ cho bạn thấy cách để thực hiện yêu cầu POST, PUT, và DELETE, làm thế nào để gửi dữ liệu Form-Urlencoded, và làm thế nào để hủy bỏ các yêu cầu.

Để tìm hiểu thêm về Retrofit, tham khảo tài liệu hướng dẫn chính thức. Và trong lúc đó, hãy xem một số khóa học khác và các hướng dẫn phát triển ứng dụng Android của chúng tôi.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.