편집 2 (2017 년 10 월) :
2017 년입니다. Retrofit을 사용하십시오. 다른 것을 사용할 이유가 거의 없습니다.
편집하다:
이 편집 당시 원래 답변은 1 년 반이 넘었습니다. 원래 답변에 제시된 개념은 여전히 유지하지만 다른 답변에서 지적했듯이 이제는이 작업을 더 쉽게 만들어주는 라이브러리가 있습니다. 더 중요한 것은 이러한 라이브러리 중 일부가 장치 구성 변경 사항을 처리한다는 것입니다.
원래 답변은 참조를 위해 아래에 보관됩니다. 하지만 시간을내어 Android 용 Rest 클라이언트 라이브러리 중 일부를 검토하여 사용 사례에 맞는지 확인하세요. 다음은 내가 평가 한 일부 라이브러리 목록입니다. 완전한 목록을 의도 한 것은 아닙니다.
원래 답변 :
Android에서 REST 클라이언트를 사용하는 방법을 제시합니다. 나는 그것이 최고라고 주장하지 않습니다 :) 또한 이것이 내 요구 사항에 대한 응답으로 생각해 낸 것입니다. 사용 사례에서 요구하는 경우 더 많은 레이어가 필요하거나 복잡성을 추가해야 할 수 있습니다. 예를 들어, 로컬 스토리지가 전혀 없습니다. 내 앱이 몇 가지 REST 응답 손실을 허용 할 수 있기 때문입니다.
내 접근 방식은 AsyncTask
덮개 아래에서 s를 사용 합니다. 제 경우에는 Activity
인스턴스 에서 이러한 태스크를 "호출" 합니다. 그러나 화면 회전과 같은 경우를 완전히 설명하려면 a Service
등에서 호출하도록 선택할 수 있습니다 .
저는 의식적으로 REST 클라이언트 자체를 API로 선택했습니다. 즉, 내 REST 클라이언트를 사용하는 앱은 실제 REST URL과 사용 된 데이터 형식을 알 필요도 없습니다.
클라이언트에는 2 개의 레이어가 있습니다.
최상위 계층 :이 계층의 목적은 REST API의 기능을 미러링하는 메서드를 제공하는 것입니다. 예를 들어 REST API의 모든 URL에 해당하는 하나의 Java 메서드 (또는 두 개-GET 용 하나와 POST 용 하나)를 가질 수 있습니다.
이것은 REST 클라이언트 API의 진입 점입니다. 이것은 앱이 일반적으로 사용하는 레이어입니다. 싱글 톤일 수 있지만 반드시 그런 것은 아닙니다.
REST 호출의 응답은이 레이어에서 POJO로 구문 분석되어 앱으로 반환됩니다.
이것은 AsyncTask
HTTP 클라이언트 메서드를 사용하여 실제로 나가서 REST 호출을 만드는 하위 계층입니다.
또한 콜백 메커니즘을 사용하여 AsyncTask
s 의 결과를 앱 에 전달하기로 결정했습니다 .
충분한 텍스트. 이제 코드를 살펴 보겠습니다. 가상 REST API URL ( http://myhypotheticalapi.com/user/profile)을 사용합니다.
최상위 레이어는 다음과 같습니다.
/**
* 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();
}
앱은 REST API에서 직접 반환 한 JSON 또는 XML (또는 다른 형식)을 사용하지 않습니다. 대신 앱은 bean 만 볼 수 Profile
있습니다.
그러면 하위 계층 (AsyncTask 계층)은 다음과 같습니다.
/**
* 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);
}
앱이 API를 사용하는 방법은 다음과 같습니다 ( Activity
또는에서 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
}
});
의견이 디자인을 설명하기에 충분하기를 바랍니다. 그러나 더 많은 정보를 제공하게되어 기쁩니다.