web-dev-qa-db-ja.com

Android RESTクライアント、サンプル?

このスレッドが答えを受け入れたとしても、他のアイデアを提案することをお気軽に、あなたは使うか好きです


私はこれらの記事に会いました:

RESTクライアントアプリケーションに関するこのGoogle I/O 2010ビデオに私を導きました

以来、アプリケーションコントローラークラスで静的コンポーネントとしてRESTコンポーネントを作成しています。

これからは、パターンを変更する必要があると思います。 Somebody 指摘した Google IOSched アプリケーションはAndroidでRESTクライアントを書く方法の素晴らしいサンプルです。 誰か他の人 この方法は複雑すぎると言いました。

だから、誰が私たちにベストプラクティスとは何かを教えてもらえますか?短く簡単な方法で。
IOSchedアプリケーションは、サンプルのユースケースには複雑すぎます。

111
Marek Sebera

編集2(2017年10月):

2017年です。レトロフィットを使用してください。他の何かを使用する理由はほとんどありません。

編集:

元の回答は、この編集の時点で1年半以上経過しています。元の回答で示された概念はまだ有効ですが、他の回答が指摘しているように、現在、このタスクを簡単にするライブラリがあります。さらに重要なことに、これらのライブラリの一部は、デバイス構成の変更を自動的に処理します。

参照用に、元の回答を以下に保持します。ただし、AndroidのRestクライアントライブラリのいくつかを調べて、ユースケースに適合するかどうかを確認してください。以下は、私が評価したいくつかのライブラリのリストです。完全なリストであることを意図したものではありません。


元の回答:

AndroidでRESTクライアントを使用するための私のアプローチを示します。私はそれが最高だと主張していません:)また、これは私が私の要求に応えて思いついたものであることに注意してください。ユースケースで要求される場合は、レイヤーを増やしたり、複雑さを追加したりする必要がある場合があります。たとえば、ローカルストレージがまったくありません。私のアプリはいくつかのREST応答の損失を許容できるためです。

私のアプローチでは、AsyncTasksのみを使用します。私の場合、これらのタスクをActivityインスタンスから「呼び出し」ます。ただし、画面の回転などのケースを完全に把握するには、Serviceなどから呼び出すことを選択できます。

RESTクライアント自体をAPIとして意識的に選択しました。つまり、私のRESTクライアントを使用するアプリは、実際のREST URLおよび使用されているデータ形式を認識する必要さえありません。

クライアントには2つの層があります。

  1. 最上層:この層の目的は、REST AP​​Iの機能をミラーリングするメソッドを提供することです。たとえば、Java AP​​IのすべてのURLに対応するRESTメソッドを1つ(または2つ-GET用とPOST用に)持つことができます。
    これは、RESTクライアントAPIへのエントリポイントです。これは、アプリが通常使用するレイヤーです。それはシングルトンである可能性がありますが、必ずしもそうではありません。
    REST呼び出しの応答は、このレイヤーによってPOJOに解析され、アプリに返されます。

  2. これは下位レベルのAsyncTask層であり、HTTPクライアントメソッドを使用して実際に外に出てREST呼び出しを行います。

さらに、コールバックメカニズムを使用してAsyncTasksの結果をアプリに返すことを選択しました。

十分なテキスト。ここでいくつかのコードを見てみましょう。架空のREST AP​​I 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 AP​​Iによって返された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
            }
        });

コメントがデザインを説明するのに十分であることを願っています。しかし、もっと情報を提供できてうれしいです。

95
curioustechizen

Virgil Dobjanschiによる「Android RESTクライアントアプリケーションの開発」は、セッション中にソースコードが提示されなかった、またはその後提供されなかったため、多くの議論につながりました。

私が知っている唯一のリファレンス実装(詳細についてはコメントしてください)は、 Datadroid (Google IOセッションは/ presentationで言及されています)で入手できます。これは、独自のアプリケーションで使用できるライブラリです。

2番目のリンクは、「最適な」RESTフレームワークを要求します。これは、stackoverflowで詳しく説明されています。私にとっては、アプリケーションのサイズが重要であり、実装のパフォーマンスがそれに続きます。

  • 通常、APIレベル1以降のAndroidの一部であるため、アプリケーションのサイズを増加させない、単純なorg.json実装を使用します。
  • 私にとって非常に興味深いのは、コメントの JSONパーサーパフォーマンス にある情報です。Android 3.0 Honeycombの時点で、GSONのストリーミングパーサーはAndroid.util.JsonReaderとして含まれています。残念ながら、コメントはもう利用できません。
  • Spring Android(私は時々使用しています)はJacksonとGSONをサポートしています。 Spring Android RestTemplate Module documentationサンプルアプリ を指します。

したがって、より複雑なシナリオではorg.jsonまたはGSONに固執します。 org.json実装のアーキテクチャでは、サーバーのユースケースを表す静的クラス(たとえば、findPerson、getPerson)を使用しています。この機能をサービスから呼び出し、マッピング(プロジェクト固有)およびネットワークIO(プレーンGETまたはPOST用の自分のRESTテンプレート)を実行しているユーティリティクラスを使用します。私はリフレクションの使用を避けようとします。

11
ChrLipp

AsynTaskを使用して、ネットワーク要求または永続化する必要があるものを実行しないでください。非同期タスクはアクティビティに強く結び付けられており、アプリの再作成後にユーザーが画面の向きを変更すると、AsyncTaskが停止します。

Intent ServiceとResultReceiverでServiceパターンを使用することをお勧めします。 RESTDroid をご覧ください。これは、あらゆる種類のREST要求を非同期に実行し、Virgil Dobjanschiのサービスパターンを実装する要求リスナーでUIに通知できるライブラリです。

7

よりクリーンな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();

新鮮ですが、とても有望に見えます。

3
Arthur

たくさんのライブラリがあり、私はこれを使用しています: https://github.com/nerde/rest-resource 。これは私が作成したものであり、ドキュメントでわかるように、他のドキュメントよりもずっと簡潔でシンプルです。 Androidに焦点を合わせていませんが、私はAndroidで使用しており、かなりうまく機能しています。

HTTP Basic Authをサポートしています。 JSONオブジェクトをシリアライズおよびデシリアライズするという汚い仕事をします。特にあなたのAPIがRailsのようなものであるなら、あなたはそれを好きになるでしょう。

1
Diego

免責事項:私はrest2mobileオープンソースプロジェクトに関与しています

RESTクライアントとしての別の選択肢は、 rest2mobile を使用することです。

アプローチは、具体的な rest examples を使用してRESTサービスのクライアントコードを生成するため、少し異なります。このコードは、REST URLおよびJSONペイロードをネイティブのJavaメソッドおよびPOJOに置き換えます。また、サーバー接続、非同期呼び出し、およびJSON変換との間のPOJOを自動的に処理します。

このツールにはさまざまなフレーバー(cli、プラグイン、Android/ios/jsサポート)があり、 Android studioプラグイン を使用してAPIをアプリに直接生成できることに注意してください。

すべてのコードは github here にあります。

1
Manu