Android REST 클라이언트, 샘플?


115

이 스레드가 답변을 수락하더라도 다른 아이디어를 자유롭게 제안하거나 사용하거나 좋아합니다.


나는 다음 기사를 만났다.

그 결과 REST 클라이언트 애플리케이션에 대한 Google I / O 2010 동영상이 표시됩니다.

지금부터 애플리케이션 컨트롤러 클래스에서 REST 구성 요소를 정적 구성 요소로 만들고 있습니다.

이제부터는 패턴을 바꿔야한다고 생각합니다. 누군가Google IOSched 애플리케이션이 Android에서 REST 클라이언트를 작성하는 방법에 대한 훌륭한 샘플 이라고 지적했습니다 . 다른 누군가 는이 방법이 너무 복잡하다고 말했습니다.

그렇다면 누구든지 모범 사례가 무엇인지 보여줄 수 있습니까? 짧고 간단한 방법입니다.
IOSched 애플리케이션은 샘플 사용 사례에 비해 너무 복잡합니다.


안녕하세요, 저는 일반적으로 "ws"라는 웹 서비스를위한 별도의 패키지를 개발하고 "WebServicUtils.java"라는 클래스를 일반화했습니다. WebServiceUtils.java 클래스에는 웹 서비스에 액세스하는 메서드가 있습니다. 내 기술이 최고인지 아닌지 확실하지 않지만 Android 애플리케이션에서 내 ws 패키지를 복사 할 때마다 재사용 할 수 있습니다. 내 기술에 대해 더 알고 싶으면 알려주세요.
Ketan Parmar 2011

나는 유튜브 댓글 작성자가 더 나은 대안을 가지고 있다고 생각하지 않습니다. Android의 API가 종종 지나치게 복잡하고 장황한 말도 안되는 경우에도 Android API 내에서 작업해야합니다.
Timmmm

참고로 Android 용 오픈 소스 이클립스 플러그인 인 Mechanoid는 간단한 DSL을 사용하여 JSON-REST 클라이언트를 생성 할 수 있습니다. 사용 방법에 대한 가이드는 여기 robotoworks.com/mechanoid-plugin/service-client-dsl 에서 찾을 수 있습니다. (나는 뻔뻔한 플러그 미안,이 플러그인의 저자!)
이안 워릭

이는 Android REST 클라이언트 구현을 배우는 사람들에게 매우 유용 할 수 있습니다. Dobjanschi의 프레젠테이션을 PDF로 변환 : drive.google.com/file/d/0B2dn_3573C3RdlVpU2JBWXdSb3c/…
Kay Zed

답변:


99

편집 2 (2017 년 10 월) :

2017 년입니다. Retrofit을 사용하십시오. 다른 것을 사용할 이유가 거의 없습니다.

편집하다:

이 편집 당시 원래 답변은 1 년 반이 넘었습니다. 원래 답변에 제시된 개념은 여전히 ​​유지하지만 다른 답변에서 지적했듯이 이제는이 작업을 더 쉽게 만들어주는 라이브러리가 있습니다. 더 중요한 것은 이러한 라이브러리 중 일부가 장치 구성 변경 사항을 처리한다는 것입니다.

원래 답변은 참조를 위해 아래에 보관됩니다. 하지만 시간을내어 Android 용 Rest 클라이언트 라이브러리 중 일부를 검토하여 사용 사례에 맞는지 확인하세요. 다음은 내가 평가 한 일부 라이브러리 목록입니다. 완전한 목록을 의도 한 것은 아닙니다.


원래 답변 :

Android에서 REST 클라이언트를 사용하는 방법을 제시합니다. 나는 그것이 최고라고 주장하지 않습니다 :) 또한 이것이 내 요구 사항에 대한 응답으로 생각해 낸 것입니다. 사용 사례에서 요구하는 경우 더 많은 레이어가 필요하거나 복잡성을 추가해야 할 수 있습니다. 예를 들어, 로컬 스토리지가 전혀 없습니다. 내 앱이 몇 가지 REST 응답 손실을 허용 할 수 있기 때문입니다.

내 접근 방식은 AsyncTask덮개 아래에서 s를 사용 합니다. 제 경우에는 Activity인스턴스 에서 이러한 태스크를 "호출" 합니다. 그러나 화면 회전과 같은 경우를 완전히 설명하려면 a Service등에서 호출하도록 선택할 수 있습니다 .

저는 의식적으로 REST 클라이언트 자체를 API로 선택했습니다. 즉, 내 REST 클라이언트를 사용하는 앱은 실제 REST URL과 사용 된 데이터 형식을 알 필요도 없습니다.

클라이언트에는 2 개의 레이어가 있습니다.

  1. 최상위 계층 :이 계층의 목적은 REST API의 기능을 미러링하는 메서드를 제공하는 것입니다. 예를 들어 REST API의 모든 URL에 해당하는 하나의 Java 메서드 (또는 두 개-GET 용 하나와 POST 용 하나)를 가질 수 있습니다.
    이것은 REST 클라이언트 API의 진입 점입니다. 이것은 앱이 일반적으로 사용하는 레이어입니다. 싱글 톤일 수 있지만 반드시 그런 것은 아닙니다.
    REST 호출의 응답은이 레이어에서 POJO로 구문 분석되어 앱으로 반환됩니다.

  2. 이것은 AsyncTaskHTTP 클라이언트 메서드를 사용하여 실제로 나가서 REST 호출을 만드는 하위 계층입니다.

또한 콜백 메커니즘을 사용하여 AsyncTasks 의 결과를 앱 에 전달하기로 결정했습니다 .

충분한 텍스트. 이제 코드를 살펴 보겠습니다. 가상 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
            }
        });

의견이 디자인을 설명하기에 충분하기를 바랍니다. 그러나 더 많은 정보를 제공하게되어 기쁩니다.


나는 아주 좋은 코드의 예 때문에이 대답을 더 좋아합니다. 감사합니다
마렉 Sebera

1
아마도 아무것도 가치가 없을 것입니다. 이것은 Virgil Dobjanschi가 설명한 것처럼 적절한 RESTful MVC 패턴을 실제로 따르지 않습니다. 앱이 직접 사용하는 SQLite 데이터베이스를 사용하는 전체 ContentProvider 레이어를 통합해야합니다. 그렇지 않으면 Android 용 경량 REST 클라이언트입니다.
쿠퍼

1
하나 개의 작은 것은, 당신은 그 가져 오기를 실행 호출해야합니다 / PostTask의
모 Kargas

1
이것은 정말 대단합니다. GetResponseCallback을 더 일반적으로 만들어 프로필 만 다시 전달하지 않도록하려면 어떻게해야합니까? 아니면 API의 각 데이터 유형에 대해 별도의 GetResponseCallback을 만드는 것이 좋습니다.

1
@MichaelHerbig 네, GetResponseCallback좀 더 일반적인 방법이 있습니다 . 내가 선호하는 것은 마커 인터페이스 를 사용하는 것입니다 . Like interface IGetResopnse{} 는 응답이 될 수있는 모든 클래스를 나타냅니다. 그럼,이 class Profile implements IGetResponse마지막으로 등 만들기 GetResponseCallback와 일반 IGetResponse상한으로 : public abstract class GetResponseCallback<? extends IGetResponse>.
curioustechizen

11

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 템플릿)를 수행하는 유틸리티 클래스를 사용합니다. 나는 반사의 사용을 피하려고 노력합니다.


4
O'Reilly 책, Programming Android는 Dobjanschi의 RESTful MVC 패턴을 완벽하게 구현합니다 (12-13 장).
쿠퍼

힌트를 보내 주셔서 감사합니다. Amazon에서 다음과 같은 진술을 발견했습니다. "12 장 및 13 장에서는 콘텐츠 제공 업체를 다루고 있습니다. 콘텐츠 제공 업체를 예제 코드와 샘플 애플리케이션으로 광범위하게 처리 한 결과이 기술이 어떻게 작동하고 어떻게 작동하는지에 대한 몇 가지 새로운 통찰력을 얻을 수있었습니다. 실제 프로그래밍 상황에서 사용할 수 있습니다. URI를 사용하여 데이터를 저장하고 참조하기위한 콘텐츠 제공 업체 프레임 워크는 Android 운영 체제의 새로운 기능 중 하나입니다. 기술을 단계별로 설명하는 데 훌륭합니다! "
ChrLipp

2
코드는 github.com/bmeike/ProgrammingAndroid2Examples에 있습니다 (하지만 챕터가 없습니다. 첫 번째 버전 코드 github.com/bmeike/ProgrammingAndroidExamples 에서 찾을 수 있습니다 )
ChrLipp

ICS +에서이 코드를 실행할 수있는 사람이 있습니까? FinchVideo 예제의 할일 파일은 "-ICS에서 충돌"이라고 간결하게 설명합니다. 나는 다소 ... 예를 파괴하는 코드를 발견하기 위해 책을 구입 후 실망했다
eageranalyst

7

AsynTask를 사용하여 네트워크 요청을 수행하거나 유지해야하는 모든 작업을 수행하지 마십시오. 비동기 작업은 활동과 밀접하게 관련되어 있으며 앱이 다시 생성 된 이후 사용자가 화면 방향을 변경하면 AsyncTask가 중지됩니다.

Intent Service 및 ResultReceiver와 함께 Service pattern을 사용하는 것이 좋습니다. RESTDroid를 살펴 보십시오 . 모든 종류의 REST 요청을 비동기식으로 수행하고 Virgil Dobjanschi의 서비스 패턴을 구현하는 요청 리스너로 UI에 알릴 수있는 라이브러리입니다.


3

훨씬 더 깨끗한 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();

신선하지만 매우 유망 해 보입니다.


활동이 종료되면 AsyncTask가 종료되기 때문에 장기 실행 요청 및 활동 간 전환에 좋지 않은 AsyncTask에서 실행되는 것 같습니다.
Malachiasz 2014 년

1

거기에는 많은 라이브러리가 있으며 https://github.com/nerde/rest-resource를 사용하고 있습니다 . 이것은 저에 의해 만들어졌으며 문서에서 볼 수 있듯이 다른 것보다 훨씬 깨끗하고 간단합니다. 그것은 안드로이드에 초점을 맞추지 않았지만 그것을 사용하고 있으며 꽤 잘 작동합니다.

HTTP 기본 인증을 지원합니다. JSON 객체를 직렬화 및 역 직렬화하는 더러운 작업을 수행합니다. 특히 API가 Rails와 같은 경우 좋아할 것입니다.


1

면책 조항 : 저는 rest2mobile 오픈 소스 프로젝트에 참여하고 있습니다.

REST 클라이언트로서의 또 다른 대안은 rest2mobile 을 사용하는 입니다.

이 접근 방식은 구체적인 나머지 예제 를 사용 하여 REST 서비스에 대한 클라이언트 코드를 생성 하므로 약간 다릅니다 . 이 코드는 REST URL 및 JSON 페이로드를 네이티브 Java 메서드 및 POJO로 대체합니다. 또한 서버 연결, 비동기 호출 및 POJO와 JSON 변환을 자동으로 처리합니다.

이 도구는 다양한 버전 (cli, 플러그인, android / ios / js 지원)으로 제공되며 Android 스튜디오 플러그인 을 사용하여 API를 앱에 직접 생성 할 수 있습니다.

모든 코드는 여기 github에서 찾을 수 있습니다 .


3
귀하의 사이트를 광고하는 대신 첫 번째 링크를 실제 타겟으로 바꾸십시오.
Skydan 2016

0

Android 용 경량 비동기 REST 클라이언트 라이브러리를 오픈 소스로 제공했습니다. 최소한의 요구 사항이 있고 멀티 스레딩을 직접 처리하고 싶지 않은 경우 유용 할 수 있습니다. 기본 통신에는 매우 적합하지만 완전한 REST 클라이언트는 아닙니다. 도서관.

libRESTfulClient라고 하며 GitHub에서 찾을 수 있습니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.