CHỈNH SỬA 2 (tháng 10 năm 2017):
Đó là năm 2017. Chỉ cần sử dụng Retrofit. Hầu như không có lý do gì để sử dụng bất cứ thứ gì khác.
BIÊN TẬP:
Câu trả lời ban đầu là hơn một năm rưỡi tại thời điểm chỉnh sửa này. Mặc dù các khái niệm được trình bày trong câu trả lời gốc vẫn được giữ nguyên, như các câu trả lời khác đã chỉ ra, hiện nay có các thư viện giúp bạn thực hiện công việc này dễ dàng hơn. Quan trọng hơn, một số thư viện này xử lý các thay đổi cấu hình thiết bị cho bạn.
Câu trả lời gốc được giữ lại bên dưới để tham khảo. Nhưng cũng vui lòng dành thời gian để kiểm tra một số thư viện máy khách Rest dành cho Android để xem chúng có phù hợp với các trường hợp sử dụng của bạn hay không. Sau đây là danh sách một số thư viện mà tôi đã đánh giá. Nó hoàn toàn không nhằm mục đích trở thành một danh sách đầy đủ.
Câu trả lời gốc:
Trình bày cách tiếp cận của tôi để có khách hàng REST trên Android. Tôi không khẳng định nó là tốt nhất mặc dù :) Ngoài ra, hãy lưu ý rằng đây là những gì tôi đã đưa ra để đáp ứng yêu cầu của tôi. Bạn có thể cần phải có nhiều lớp / thêm độ phức tạp nếu trường hợp sử dụng của bạn yêu cầu nó. Ví dụ: tôi không có bộ nhớ cục bộ nào cả; vì ứng dụng của tôi có thể chịu được việc mất một vài phản hồi REST.
Phương pháp tiếp cận của tôi chỉ sử dụng AsyncTask
các trang bìa. Trong trường hợp của tôi, tôi "gọi" các Tác vụ này từ Activity
phiên bản của tôi ; nhưng để giải thích đầy đủ các trường hợp như xoay màn hình, bạn có thể chọn gọi chúng từService
hoặc như vậy.
Tôi đã chọn ứng dụng khách REST của mình một cách có ý thức làm API. Điều này có nghĩa là ứng dụng sử dụng ứng dụng khách REST của tôi thậm chí không cần biết về URL REST thực và định dạng dữ liệu được sử dụng.
Khách hàng sẽ có 2 lớp:
Lớp trên cùng: Mục đích của lớp này là cung cấp các phương thức phản ánh chức năng của API REST. Ví dụ: bạn có thể có một phương thức Java tương ứng với mọi URL trong API REST của bạn (hoặc thậm chí hai - một cho GET và một cho POST).
Đây là điểm nhập vào API ứng dụng khách REST. Đây là lớp mà ứng dụng sẽ sử dụng bình thường. Nó có thể là một singleton, nhưng không nhất thiết.
Phản hồi của cuộc gọi REST được lớp này phân tích cú pháp thành một POJO và trả về ứng dụng.
Đây là AsyncTask
lớp cấp thấp hơn , sử dụng các phương thức máy khách HTTP để thực sự đi ra ngoài và thực hiện cuộc gọi REST đó.
Ngoài ra, tôi đã chọn sử dụng cơ chế Gọi lại để thông báo kết quả AsyncTask
quay lại ứng dụng.
Văn bản đủ rồi. Bây giờ chúng ta hãy xem một số mã. Hãy lấy một URL REST API giả định - http://myhypotheticalapi.com/user/profile
Lớp trên cùng có thể trông như thế này:
/**
* Entry point into the API.
*/
public class HypotheticalApi{
public static HypotheticalApi getInstance(){
//Choose an appropriate creation strategy.
}
/**
* Request a User Profile from the REST server.
* @param userName The user name for which the profile is to be requested.
* @param callback Callback to execute when the profile is available.
*/
public void getUserProfile(String userName, final GetResponseCallback callback){
String restUrl = Utils.constructRestUrlForProfile(userName);
new GetTask(restUrl, new RestTaskCallback (){
@Override
public void onTaskComplete(String response){
Profile profile = Utils.parseResponseAsProfile(response);
callback.onDataReceived(profile);
}
}).execute();
}
/**
* Submit a user profile to the server.
* @param profile The profile to submit
* @param callback The callback to execute when submission status is available.
*/
public void postUserProfile(Profile profile, final PostCallback callback){
String restUrl = Utils.constructRestUrlForProfile(profile);
String requestBody = Utils.serializeProfileAsString(profile);
new PostTask(restUrl, requestBody, new RestTaskCallback(){
public void onTaskComplete(String response){
callback.onPostSuccess();
}
}).execute();
}
}
/**
* Class definition for a callback to be invoked when the response data for the
* GET call is available.
*/
public abstract class GetResponseCallback{
/**
* Called when the response data for the REST call is ready. <br/>
* This method is guaranteed to execute on the UI thread.
*
* @param profile The {@code Profile} that was received from the server.
*/
abstract void onDataReceived(Profile profile);
/*
* Additional methods like onPreGet() or onFailure() can be added with default implementations.
* This is why this has been made and abstract class rather than Interface.
*/
}
/**
*
* Class definition for a callback to be invoked when the response for the data
* submission is available.
*
*/
public abstract class PostCallback{
/**
* Called when a POST success response is received. <br/>
* This method is guaranteed to execute on the UI thread.
*/
public abstract void onPostSuccess();
}
Lưu ý rằng ứng dụng không sử dụng JSON hoặc XML (hoặc bất kỳ định dạng nào khác) do REST API trả về trực tiếp. Thay vào đó, ứng dụng chỉ nhìn thấy hạt đậu Profile
.
Sau đó, lớp dưới (lớp AsyncTask) có thể trông như thế này:
/**
* An AsyncTask implementation for performing GETs on the Hypothetical REST APIs.
*/
public class GetTask extends AsyncTask<String, String, String>{
private String mRestUrl;
private RestTaskCallback mCallback;
/**
* Creates a new instance of GetTask with the specified URL and callback.
*
* @param restUrl The URL for the REST API.
* @param callback The callback to be invoked when the HTTP request
* completes.
*
*/
public GetTask(String restUrl, RestTaskCallback callback){
this.mRestUrl = restUrl;
this.mCallback = callback;
}
@Override
protected String doInBackground(String... params) {
String response = null;
//Use HTTP Client APIs to make the call.
//Return the HTTP Response body here.
return response;
}
@Override
protected void onPostExecute(String result) {
mCallback.onTaskComplete(result);
super.onPostExecute(result);
}
}
/**
* An AsyncTask implementation for performing POSTs on the Hypothetical REST APIs.
*/
public class PostTask extends AsyncTask<String, String, String>{
private String mRestUrl;
private RestTaskCallback mCallback;
private String mRequestBody;
/**
* Creates a new instance of PostTask with the specified URL, callback, and
* request body.
*
* @param restUrl The URL for the REST API.
* @param callback The callback to be invoked when the HTTP request
* completes.
* @param requestBody The body of the POST request.
*
*/
public PostTask(String restUrl, String requestBody, RestTaskCallback callback){
this.mRestUrl = restUrl;
this.mRequestBody = requestBody;
this.mCallback = callback;
}
@Override
protected String doInBackground(String... arg0) {
//Use HTTP client API's to do the POST
//Return response.
}
@Override
protected void onPostExecute(String result) {
mCallback.onTaskComplete(result);
super.onPostExecute(result);
}
}
/**
* Class definition for a callback to be invoked when the HTTP request
* representing the REST API Call completes.
*/
public abstract class RestTaskCallback{
/**
* Called when the HTTP request completes.
*
* @param result The result of the HTTP request.
*/
public abstract void onTaskComplete(String result);
}
Đây là cách một ứng dụng có thể sử dụng API (trong một Activity
hoặc Service
):
HypotheticalApi myApi = HypotheticalApi.getInstance();
myApi.getUserProfile("techie.curious", new GetResponseCallback() {
@Override
void onDataReceived(Profile profile) {
//Use the profile to display it on screen, etc.
}
});
Profile newProfile = new Profile();
myApi.postUserProfile(newProfile, new PostCallback() {
@Override
public void onPostSuccess() {
//Display Success
}
});
Tôi hy vọng các ý kiến là đủ để giải thích thiết kế; nhưng tôi rất vui khi cung cấp thêm thông tin.