Полезное для Android разработчика #Square Часть 1

от автора

На этой недели дайджест не простой и посвещен он компании Square Inc, которая разрабатывает удобные библиотеки, которые во многом облегчают нам работу в повседневном программировании 🙂

Retrofit

Превращает REST API сервис в Java Interface
Пример:

public interface GitHubService {   @GET("/users/{user}/repos")   List<Repo> listRepos(@Path("user") String user); } 

Для работы необходимо RestAdapter сгенерирует код взаимодействия с вашим интерфейсом.

RestAdapter restAdapter = new RestAdapter.Builder()     .setEndpoint("https://api.github.com")     .build();  GitHubService service = restAdapter.create(GitHubService.class); 

И теперь в при каждом вызове сгенерированного GitHubService будет посылать HTTP запрос на сервер

List<Repo> repos = service.listRepos("octocat");

Используйте аннотации для описания ваших HTTP запросов

  • Подстановка в URL параметров, и поддержка запросов
  • Превращение объекта в тело запроса(JSON, Protocol buffers)
  • Мульти запросы объектов и передача файлов

Описание API

Аннотации в ваших методах интерфейса и параметрах помогут сформировать более точный запрос

Методы запросов

Каждый метод HTTP запроса должен быть аннотирован, для построения отностильной ссылки на сервер, Реализованно 5 методов аннотаций
GET, POST, PUT, DELETE и HEAD. Ссылка будет сконструированна взависимости от вашей аннотации

@GET("/users/list")

Вы также можете легко создавать запросы примиком из аннотаций

@GET("/users/list?sort=desc")

Манипуляция с ссылками

Ссылка на запрос может быть динамичной, используйте подстановочные блоки и параметры в методах. Подстановочные блоки это строки которые обернуты в фигурные скобки, пример: {id}, и переменная которая должна подставить должна быть аннотированна Path

@GET("/group/{id}/users") List<User> groupList(@Path("id") int groupId); 

Также можно и создавать запросы

@GET("/group/{id}/users") List<User> groupList(@Path("id") int groupId, @Query("sort") String sort); 

Для отправки множественных запросов используйте аннотацию Map

@GET("/group/{id}/users") List<User> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options); 

Запросы с объектами

Вы также можете отправлять объекты в тело HTTP запроса с помощью аннотации Body

@POST("/users/new") void createUser(@Body User user, Callback<User> cb); 

Ваш объект будет сконвертированов созданным вами RestAdapter’ским конвертатором (о как перевел я)

Отправка форм

Ваши методы могут быть объявлены для перекодирования и отправки ввиде формы
Запросы в форме отправляются с помощью @FormUrlEncoded аннотацией
и каждое поле формы должно быть аннотированно @Field ом

@FormUrlEncoded @POST("/user/edit") User updateUser(@Field("first_name") String first, @Field("last_name") String last); 

Multipart(не знаю как перевсти) запросы должны быть аннотированы с помощью @Multipart

@Multipart @PUT("/user/photo") User updateUser(@Part("photo") TypedFile photo, @Part("description") TypedString description); 

Манипуляция с заголовками

Вы также можете управлять заголовками вашего запроса используя Header

@Headers("Cache-Control: max-age=640000") @GET("/widget/list") List<Widget> widgetList(); 
@Headers({     "Accept: application/vnd.github.v3.full+json",     "User-Agent: Retrofit-Sample-App" }) @GET("/users/{username}") User getUser(@Path("username") String username); 

Примечание* заголвки не переписываются, Все заголвки с таким же имененм будут включены в запрос.

Запросы с Загловком могут быть обновлены динамически используя все тот же Header, строка может быть включена в заголовок если она не является Null объектом

@GET("/user") void getUser(@Header("Authorization") String authorization, Callback<User> callback) 

Заголовки которые должны быть включены в каждый запрос могут быть транслированны в RequestInterceptor, Следующий код создает RequestInterceptor который добавляет User-Agent в каждый запрос

RequestInterceptor requestInterceptor = new RequestInterceptor() {   @Override   public void intercept(RequestFacade request) {     request.addHeader("User-Agent", "Retrofit-Sample-App");   } };  RestAdapter restAdapter = new RestAdapter.Builder()   .setEndpoint("https://api.github.com")   .setRequestInterceptor(requestInterceptor)   .build(); 

Синхронный vs Асинхронные vs Observable

Ваши методы могут быть задеклорированны для синхронной и асихрнной отправки.

Ниже приведенный метод будет вызван синхронной отправкой

@GET("/user/{id}/photo") Photo getUserPhoto(@Path("id") int id); 

Теперь асинхронный

@GET("/user/{id}/photo") void getUserPhoto(@Path("id") int id, Callback<Photo> cb); 

Разница в том что асинхронный метод должен имнеть в конце Callback и ничего не возвращать
В андроиде Callback’и будут вызваны в UI потоке.

Retrofit также интегрирован с RxJava для поддержки rx.Observable

@GET("/user/{id}/photo") Observable<Photo> getUserPhoto(@Path("id") int id); 

Observable запросы посылаются асинхронно, а также просматриваются в в том же потоке, что и HTTP запросы, для обработки в разных потоках используйте вызовите метод observerOn(Scheduler) в возвращенном Observable

Обработка ответов

HTTP ответы могут автоматически сконвертироваться в указонный объект, используется RestAdapter’овский GSON ковертор. Указать объект вы можете при возвращении, Сallback или Observable

@GET("/users/list") List<User> userList();  @GET("/users/list") void userList(Callback<List<User>> cb);  @GET("/users/list") Observable<List<User>> userList(); 

Для получения доступка к необработанному ответу выполните следующее

@GET("/users/list") Response userList();  @GET("/users/list") void userList(Callback<Response> cb);  @GET("/users/list") Observable<Response> userList(); 

Конфигурация RestAdapter

Вы также можете настроить ваш RestAdapter, сбив настройки по умолчанию 😉

Настройка JSON конвертора

Retrofit использует по умолчанию GSON библиотеку для обработки JSON ответов или объектов в тело HTTP запроса, Вы всегда можете настроить его под свои нужды

Gson gson = new GsonBuilder()     .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)     .registerTypeAdapter(Date.class, new DateTypeAdapter())     .create();  RestAdapter restAdapter = new RestAdapter.Builder()     .setEndpoint("https://api.github.com")     .setConverter(new GsonConverter(gson))     .build();  GitHubService service = restAdapter.create(GitHubService.class); 

Каждый ответ обрабатывается указанным в RestAdapter конвертором

Обработка нестандартных форматов

По умолчанию Retrofit конвертирует только Json. Но также и имеются простые реализации обработки XML, для полного ознакомления взгляните на спиок Retorfit-конверторов
Теперь простая реализация XML конвертора

RestAdapter restAdapter = new RestAdapter.Builder()     .setEndpoint("https://api.soundcloud.com")     .setConverter(new SimpleXMLConverter())     .build();  SoundCloudService service = restAdapter.create(SoundCloudService.class); 

Обработка ошбок

Если вам нужен свой обработчик ошибок, предусматривают свою реализацию класса ErrorHandler, Ниже приведенны код показывает как обрабатывать ошибки, когда в HTTP запросе произошла 401 ошибка

class MyErrorHandler implements ErrorHandler {   @Override public Throwable handleError(RetrofitError cause) {     Response r = cause.getResponse();     if (r != null && r.getStatus() == 401) {       return new UnauthorizedException(cause);     }     return cause;   } }  RestAdapter restAdapter = new RestAdapter.Builder()     .setEndpoint("https://api.github.com")     .setErrorHandler(new MyErrorHandler())     .build(); 

Спасибо всем за внимания 😉

Музыка при переводе:
Lights & Motion — The March
Craig Wazbinski & R.wali Vincent — Sideways
The Family Crest — Make Me a Boat
Ruth Barrett — Earthflow
Ludovico Einaudi — Divenire
Aron Wright — In the woods
Earth Wind and Fire — September
Anywayican — Walk The Moon

А какую музыку слушаете вы?

ссылка на оригинал статьи http://habrahabr.ru/post/218355/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *