이 스레드가 답변을 수락하더라도 다른 아이디어를 자유롭게 제안하거나 사용하거나 좋아합니다.
나는 다음 기사를 만났다.
그 결과 REST 클라이언트 애플리케이션에 대한 Google I / O 2010 동영상이 표시됩니다.
지금부터 애플리케이션 컨트롤러 클래스에서 REST 구성 요소를 정적 구성 요소로 만들고 있습니다.
이제부터는 패턴을 바꿔야한다고 생각합니다. 누군가 는 Google IOSched 애플리케이션이 Android에서 REST 클라이언트를 작성하는 방법에 대한 훌륭한 샘플 이라고 지적했습니다 . 다른 누군가 는이 방법이 너무 복잡하다고 말했습니다.
그렇다면 누구든지 모범 사례가 무엇인지 보여줄 수 있습니까? 짧고 간단한 방법입니다.
IOSched 애플리케이션은 샘플 사용 사례에 비해 너무 복잡합니다.
답변
편집 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
}
});
의견이 디자인을 설명하기에 충분하기를 바랍니다. 그러나 더 많은 정보를 제공하게되어 기쁩니다.
답변
Virgil Dobjanschi의 “Android REST 클라이언트 애플리케이션 개발”은 세션 중에 소스 코드가 제공되지 않았거나 이후에 제공되지 않았기 때문에 많은 논의로 이어졌습니다.
내가 아는 유일한 참조 구현은 Datadroid 에서 사용할 수 있습니다 (더 많이 알고있는 경우 의견을 남겨주세요) (Google IO 세션은 / presentation에서 언급 됨). 자신의 응용 프로그램에서 사용할 수있는 라이브러리입니다.
두 번째 링크는 “최고의”REST 프레임 워크를 요구하며 이는 stackoverflow에 대해 많이 논의됩니다. 저에게는 애플리케이션 크기가 중요하고 그 다음으로 구현 성능이 중요합니다.
- 일반적으로 API 레벨 1부터 Android의 일부이므로 애플리케이션 크기를 늘리지 않는 일반 org.json 구현을 사용합니다.
- 저에게 매우 흥미로운 것은 주석에서 JSON 파서 성능 에 대한 정보 였습니다. Android 3.0 Honeycomb부터 GSON의 스트리밍 파서는 android.util.JsonReader로 포함되었습니다. 불행히도 댓글은 더 이상 사용할 수 없습니다.
- Spring Android (가끔 사용하는)는 Jackson과 GSON을 지원합니다. 봄 안드로이드 RestTemplate 모듈 문서 A와 점 샘플 응용 프로그램 .
따라서 복잡한 시나리오에서는 org.json 또는 GSON을 사용합니다. org.json 구현의 아키텍처를 위해 서버 사용 사례 (예 : findPerson, getPerson)를 나타내는 정적 클래스를 사용하고 있습니다. 서비스에서이 기능을 호출하고 매핑 (프로젝트 별) 및 네트워크 IO (일반 GET 또는 POST를위한 자체 REST 템플릿)를 수행하는 유틸리티 클래스를 사용합니다. 나는 반사의 사용을 피하려고 노력합니다.
답변
AsynTask를 사용하여 네트워크 요청을 수행하거나 유지해야하는 모든 작업을 수행하지 마십시오. 비동기 작업은 활동과 밀접하게 관련되어 있으며 앱이 다시 생성 된 이후 사용자가 화면 방향을 변경하면 AsyncTask가 중지됩니다.
Intent Service 및 ResultReceiver와 함께 Service pattern을 사용하는 것이 좋습니다. RESTDroid를 살펴 보십시오 . 모든 종류의 REST 요청을 비동기식으로 수행하고 Virgil Dobjanschi의 서비스 패턴을 구현하는 요청 리스너로 UI에 알릴 수있는 라이브러리입니다.
답변
훨씬 더 깨끗한 API와 형식에 안전한 데이터가있는 또 다른 라이브러리가 있습니다.
https://github.com/kodart/Httpzoid
다음은 간단한 사용 예입니다.
Http http = HttpFactory.create(context);
http.post("http://example.com/users")
.data(new User("John"))
.execute();
또는 콜백으로 더 복잡함
Http http = HttpFactory.create(context);
http.post("http://example.com/users")
.data(new User("John"))
.handler(new ResponseHandler<Void>() {
@Override
public void success(Void ignore, HttpResponse response) {
}
@Override
public void error(String message, HttpResponse response) {
}
@Override
public void failure(NetworkError error) {
}
@Override
public void complete() {
}
}).execute();
신선하지만 매우 유망 해 보입니다.
답변
거기에는 많은 라이브러리가 있으며 https://github.com/nerde/rest-resource를 사용하고 있습니다 . 이것은 저에 의해 만들어졌으며 문서에서 볼 수 있듯이 다른 것보다 훨씬 깨끗하고 간단합니다. 그것은 안드로이드에 초점을 맞추지 않았지만 그것을 사용하고 있으며 꽤 잘 작동합니다.
HTTP 기본 인증을 지원합니다. JSON 객체를 직렬화 및 역 직렬화하는 더러운 작업을 수행합니다. 특히 API가 Rails와 같은 경우 좋아할 것입니다.
답변
면책 조항 : 저는 rest2mobile 오픈 소스 프로젝트에 참여하고 있습니다.
REST 클라이언트로서의 또 다른 대안은 rest2mobile 을 사용하는 것 입니다.
이 접근 방식은 구체적인 나머지 예제 를 사용 하여 REST 서비스에 대한 클라이언트 코드를 생성 하므로 약간 다릅니다 . 이 코드는 REST URL 및 JSON 페이로드를 네이티브 Java 메서드 및 POJO로 대체합니다. 또한 서버 연결, 비동기 호출 및 POJO와 JSON 변환을 자동으로 처리합니다.
이 도구는 다양한 버전 (cli, 플러그인, android / ios / js 지원)으로 제공되며 Android 스튜디오 플러그인 을 사용하여 API를 앱에 직접 생성 할 수 있습니다.
모든 코드는 여기 github에서 찾을 수 있습니다 .
답변
Android 용 경량 비동기 REST 클라이언트 라이브러리를 오픈 소스로 제공했습니다. 최소한의 요구 사항이 있고 멀티 스레딩을 직접 처리하고 싶지 않은 경우 유용 할 수 있습니다. 기본 통신에는 매우 적합하지만 완전한 REST 클라이언트는 아닙니다. 도서관.
libRESTfulClient라고 하며 GitHub에서 찾을 수 있습니다 .