developer tip

Android REST 클라이언트, 샘플?

optionbox 2020. 7. 29. 08:08
반응형

Android REST 클라이언트, 샘플?


이 글이 답변을 수락 했더라도 다른 아이디어를 제안 해 주시기 바랍니다.


나는이 기사들을 만났다 :

REST 클라이언트 애플리케이션에 대한이 Google I / O 2010 비디오로 연결됩니다.

지금부터 Application Controller 클래스에서 REST 구성 요소를 정적 구성 요소로 만들고 있습니다.

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

그렇다면 모범 사례가 무엇인지 알려주십시오. 짧고 간단한 방법.
IOSched 애플리케이션은 샘플 사용 사례에 비해 너무 복잡합니다.


편집 2 (2017 년 10 월) :

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

편집하다:

원래 답변은이 편집 시점에서 1 년 반이 넘었습니다. 원래 답변으로 제시된 개념은 여전히 ​​유효하지만 다른 답변에서 알 수 있듯이이 작업을보다 쉽게 ​​수행 할 수있는 라이브러리가 있습니다. 더 중요한 것은 이러한 라이브러리 중 일부는 장치 구성 변경을 처리하는 것입니다.

원래 답변은 참조 용으로 아래에 유지됩니다. 그러나 시간을내어 Android 용 Rest 클라이언트 라이브러리 중 일부가 사용 사례에 적합한 지 확인하십시오. 다음은 내가 평가 한 일부 라이브러리의 목록입니다. 철저한 목록으로 의도 된 것은 아닙니다.


원래 답변 :

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

내 접근 방식은 AsyncTask표지 아래에 s를 사용 합니다. 필자의 경우에는이 작업을 Activity인스턴스 에서 "호출" 합니다. 그러나 화면 회전과 같은 경우를 완벽하게 설명하기 위해 전화를 걸 수도 있습니다 Service.

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

클라이언트는 2 개의 레이어를 갖습니다 :

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

  2. 이것은 하위 레벨 AsyncTask계층으로, HTTP 클라이언트 메소드를 사용하여 실제로 나가서 해당 REST 호출을 수행합니다.

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

충분한 텍스트. 이제 몇 가지 코드를 보자. - 가상의 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 클라이언트 애플리케이션 개발"은 세션 중에 소스 코드가 제공되지 않았거나 이후에 제공되지 않았기 때문에 많은 논의를 이끌어 냈습니다.

The only reference implementation I know (please comment if you know more) is available at Datadroid (the Google IO session is mentioned under /presentation). It is a library which you can use in your own application.

The second link asks for the "best" REST framework, which is discussed heavily on stackoverflow. For me the application size is important, followed by the performance of the implementation.

  • Normally I use the plain org.json implemantation, which is part of Android since API level 1 and therefore does not increase application size.
  • For me very interesting was the information found on JSON parsers performance in the comments: as of Android 3.0 Honeycomb, GSON's streaming parser is included as android.util.JsonReader. Unfortunately, the comments aren't available any more.
  • Spring Android (which I use sometimes) supports Jackson and GSON. The Spring Android RestTemplate Module documentation points to a sample app.

Therefore I stick to org.json or GSON for complexer scenarios. For the architecture of an org.json implementation, I am using a static class which represents the server use cases (e.g. findPerson, getPerson). I call this functionality from a service and use utility classes which are doing the mapping (project specific) and the network IO (my own REST template for plain GET or POST). I try to avoid the usage of reflection.


Never use AsynTask to perform network request or whatever that need to be persisted. Async Task are strongly tied to your activity and if the user change the orientation of the screen since the App is re created the AsyncTask will be stopped.

I suggest you to use Service pattern with Intent Service and ResultReceiver. Take a look to RESTDroid. It's a library that allows you to perform any kind of REST request asynchronously and notify your UI with Request Listeners implementing the Virgil Dobjanschi's service pattern.


There is another library with much cleaner API and type-safe data. https://github.com/kodart/Httpzoid

Here is a simple usage example

Http http = HttpFactory.create(context);
http.post("http://example.com/users")
    .data(new User("John"))
    .execute();

Or more complex with callbacks

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();

It is fresh new, but looks very promising.


There is plenty of libraries out there and I'm using this one: https://github.com/nerde/rest-resource. This was created by me, and, as you can see in the documentation, it's way cleaner and simpler than the other ones. It's not focused on Android, but I'm using in it and it's working pretty well.

It supports HTTP Basic Auth. It does the dirty job of serializing and deserializing JSON objects. You will like it, specially if your API is Rails like.


Disclaimer: I am involved in the rest2mobile open source project

Another alternative as a REST client is to use rest2mobile.

The approach is slightly different as it uses concrete rest examples to generate the client code for the REST service. The code replaces the REST URL and JSON payloads with native java methods and POJOs. It also automatically handles server connections, asynchronous invocations and POJO to/from JSON conversions.

Note that this tool comes in different flavors (cli, plugins, android/ios/js support) and you can use the android studio plugin to generate the API directly into your app.

All the code can be found on github here.

참고URL : https://stackoverflow.com/questions/8267928/android-rest-client-sample

반응형