Клієнт Android REST, зразок?


115

Навіть якщо ця нитка прийняла відповідь, сміливо пропонуйте інші ідеї, якими ви користуєтесь чи подобаєтесь


Я зустрів ці статті:

І це привело мене до цього відео в I / O 2010 Google про клієнтські програми REST

З цього часу я створюю REST компонент як статичний компонент у своєму класі контролерів програми.

З цього моменту, я думаю, я повинен змінити схему. Хтось зазначав, що додаток Google IOSched - це чудовий зразок того, як писати клієнтів REST на Android. Хтось ще сказав, що ці способи занадто складні.

Тож чи може хто-небудь показати нам, яка найкраща практика? Коротко і просто.
Додаток IOSched занадто складний для зразкового використання.


Привіт, загалом я розробляю окремий пакет для веб-сервісу під назвою "ws", узагальнив клас під назвою "WebServicUtils.java". Клас WebServiceUtils.java має методи доступу до веб-сервісу. Я не впевнений, що моя техніка найкраща чи ні, але вона повторно використовується щоразу, коли я копіюю свій пакет ws в програму Android, повідомте мені, чи хочете ви дізнатися більше про мою техніку.
Кетан Пармар

Я не думаю, що у коментатора YouTube є краща альтернатива. Ми повинні працювати в API-програмах Android, навіть якщо вони часто є шалено надмірно складними та багатослівними дурницями.
Timmmm

В якості додаткового зауваження, Mechanoid, плагін відкритого джерела затемнення для Android може генерувати клієнтів JSON-REST за допомогою простого DSL, керівництво щодо його використання можна знайти тут robotoworks.com/mechanoid-plugin/service-client-dsl (Я автор цього плагіна, вибачте за безсоромний штекер!)
Ian Warwick

Це може бути дуже корисно для людей, які навчаються впровадженню клієнта Android REST. Презентація Dobjanschi перетворена на PDF: drive.google.com/file/d/0B2dn_3573C3RdlVpU2JBWXdSb3c/…
Kay Zed

Відповіді:


99

EDIT 2 (жовтень 2017):

Це 2017. Просто використовуйте Retrofit. Причин використовувати інше майже немає.

Редагувати:

Оригінальна відповідь на момент редагування становила понад півтора року. Хоча поняття, представлені в оригінальній відповіді, все ще зберігаються, як вказують інші відповіді, зараз там є бібліотеки, які полегшують вам це завдання. Що ще важливіше, деякі з цих бібліотек обробляють зміни конфігурації пристрою для вас.

Оригінал відповіді зберігається нижче для довідки. Але також знайдіть час, щоб вивчити деякі бібліотеки клієнтів «Відпочинок» для Android, щоб побачити, чи відповідають вони вашим випадкам використання. Далі подано список деяких бібліотек, які я оцінив. Це аж ніяк не є вичерпним списком.


Оригінальний відповідь:

Представляю мій підхід до отримання REST-клієнтів на Android. Я не стверджую, що це найкраще :) Також зауважте, що саме це я придумав у відповідь на мою вимогу. Можливо, вам доведеться мати більше шарів / додати більше складності, якщо цього вимагає ваш випадок використання. Наприклад, я зовсім не маю локального сховища; тому що мій додаток може терпіти втрату кількох відповідей REST.

Мій підхід використовує тільки AsyncTasks під прикриттями. У моєму випадку я "викликаю" ці Завдання зі свого Activityпримірника; але для повного обліку випадків, таких як обертання екрана, ви можете обрати їх до того Serviceчи іншого.

Я свідомо вибрав свого клієнта REST як API. Це означає, що додаток, який використовує мій REST-клієнт, навіть не повинен знати про фактичні URL-адреси REST та використовуваний формат даних.

Клієнт матиме два шари:

  1. Верхній шар: Метою цього шару є надання методів, що відображають функціональність API REST. Наприклад, у вас може бути один метод Java, відповідний кожній URL-адресі вашого REST API (або навіть два - один для GET та один для POST).
    Це точка входу в API клієнта REST. Це шар, який додаток використовує нормально. Це може бути сингл, але не обов’язково.
    Відповідь на виклик REST цей рівень аналізується на POJO та повертається в додаток.

  2. Це нижчий рівень AsyncTask, який використовує клієнтські методи HTTP для фактичного виходу та здійснення цього REST-дзвінка.

Крім того, я вирішив використовувати механізм AsyncTaskзворотного виклику для передачі результату s назад до програми.

Досить тексту. Давайте зараз подивимось якийсь код. Дозволяє приймати гіпотетичну URL-адресу API REST - 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();

}

Зауважте, що додаток не використовує JSON або XML (або будь-який інший формат), повернений API REST безпосередньо. Натомість додаток бачить лише квасоля 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
            }
        });

Я сподіваюся, що коментарів достатньо для пояснення дизайну; але я б радий надати більше інформації.


Мені ця відповідь більше подобається завдяки прикладам досить приємного коду. Спасибі
Марек Себера

1
Напевно, нічого не варто, це насправді не відповідає правильній схемі RESTful MVC, як описав Вергілій Добянскі. Вам потрібно буде включити повний рівень ContentProvider, який використовує базу даних SQLite, яку безпосередньо використовує додаток. В іншому випадку це хороший, легкий клієнт REST для Android.
Купер

1
Одне невелике, вам потрібно буде зателефонувати виконувати на тих, хто отримує / PostTask
Mo Kargas

1
Це справді чудово. Як я можу зробити GetResponseCallback більш загальним, щоб він не передав лише профіль назад, або ви б запропонували зробити окремий GetResponseCallback для кожного типу даних з API?

1
@MichaelHerbig Так, є способи зробити GetResponseCallbackбільш загальними. Я вважаю за краще використовувати інтерфейс маркера : люблю interface IGetResopnse{} позначати всі класи, які можуть бути відповідями. Тоді, я і class Profile implements IGetResponseт.д. І, нарешті, зробити GetResponseCallbackспільний з IGetResponseяк верхня межа : public abstract class GetResponseCallback<? extends IGetResponse>.
цікавийтехнік

11

"Розвиток клієнтських програм Android REST" Віргілія Доб'янського спричинив багато обговорень, оскільки жоден вихідний код не був представлений під час сесії та не наданий після цього.

Єдина відома для мене посилання (будь ласка, прокоментуйте, якщо ви знаєте більше) доступна на Datadroid (сесія Google IO згадується в розділі / презентація). Це бібліотека, яку ви можете використовувати у власній програмі.

Друга посилання вимагає "найкращої" рамки REST, про яку велика кількість обговорюється в потоковому потоці. Для мене важливий розмір програми з подальшим результатом виконання.

  • Зазвичай я використовую звичайну програму org.json, яка є частиною Android, починаючи з рівня 1 API, і тому не збільшує розмір програми.
  • Для мене дуже цікавою була інформація про продуктивність парсерів JSON у коментарях: як для Android 3.0 Honeycomb, потоковий аналізатор GSON включений як android.util.JsonReader. На жаль, коментарі більше не доступні.
  • Весняний Android (який я іноді використовую) підтримує Джексона та GSON. У RestTemplate Модуль Spring Android документації вказує на приклад програми .

Тому я дотримуюся org.json або GSON для складніших сценаріїв. Для архітектури реалізації org.json я використовую статичний клас, який представляє випадки використання сервера (наприклад, findPerson, getPerson). Я називаю цю функціональність за допомогою сервісу і використовую утилітні класи, які роблять відображення (специфічний для проекту) та мережевий IO (мій власний шаблон REST для звичайного GET або POST). Я намагаюся уникати використання рефлексії.


4
Книга O'Reilly, Програмування Android, має повну реалізацію шаблону RESTful MVC Dobjanschi (глави 12-13).
Купер

Дякую за підказку: я виявив це твердження в Amazon: "Розділи 12 і 13 стосуються постачальників вмісту. Широке звернення до постачальників вмісту з прикладом коду та зразкового додатку дало мені кілька нових розумінь того, як працює ця технологія та як вона може використовуватися в реальних програмуючих ситуаціях. Рамка постачальника вмісту для зберігання та посилання даних за допомогою URI є однією з нових особливостей операційної системи Android. Велика робота в поясненні технології поетапно! "
ChrLipp

2
Код знаходиться на github.com/bmeike/ProgrammingAndroid2Examples (але глави відсутні, їх можна знайти в першому виданні код github.com/bmeike/ProgrammingAndroidExamples )
ChrLipp

Хтось зміг запустити цей код на ICS +? Файл todo у прикладі FinchVideo лаконічно зазначає "- Збої під ICS". Я був дещо розчарований, купивши книгу, щоб виявити, що приклади коду порушені ...
eageranalyst

7

Ніколи не використовуйте AsynTask для виконання мережевого запиту або будь-якого іншого, що потрібно зберігати. Завдання Async сильно пов'язана з вашою діяльністю, і якщо користувач змінить орієнтацію екрана з моменту створення додатка, AsyncTask буде зупинено.

Я пропоную вам скористатися схемою обслуговування з Intent Service та ResultReceiver. Погляньте на RESTDroid . Це бібліотека, яка дозволяє вам виконувати будь-який тип REST-запиту асинхронно та повідомляти свій інтерфейс користувача з запитуючими слухачами, що реалізують схему обслуговування Virgil Dobjanschi.


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 буде вбито, коли активність завершиться.
Малахіаш

1

Бібліотеки там багато, і я використовую цю: https://github.com/nerde/rest-resource . Це було створено мною, і, як ви бачите в документації, він чистіший і простіший за інші. Він не зосереджений на Android, але я використовую його, і він працює досить добре.

Він підтримує HTTP Basic Auth. Це робить брудну роботу по серіалізації та десеріалізації об'єктів JSON. Вам сподобається, особливо якщо ваш API такий, як Rails.


1

Відмова: Я беру участь у проекті open2mobile з відкритим кодом

Ще одна альтернатива як REST-клієнта - використовувати rest2mobile .

Підхід дещо інший, оскільки він використовує конкретні приклади відпочинку для створення коду клієнта для REST-послуги. Код замінює URL-адресу REST та корисні навантаження JSON власними методами Java та POJO. Він також автоматично обробляє з'єднання з сервером, асинхронні виклики та POJO в / з конверсій JSON.

Зауважте, що цей інструмент має різні смаки (cli, плагіни, підтримка android / ios / js), і ви можете використовувати плагін Android Studio для створення API безпосередньо у вашому додатку.

Весь код можна знайти на Github тут .


3
Будь ласка, замініть перше посилання на фактичну ціль, а не рекламуйте свій сайт.
Skydan

0

У нас є легка бібліотека клієнтів async REST для Android, яка може бути корисною, якщо ви маєте мінімальні вимоги та не хочете самостійно обробляти багатопотоковість - це дуже добре для базових комунікацій, але не повноцінний клієнт REST бібліотека.

Він називається libRESTfulClient і його можна знайти на GitHub .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.