...

суббота, 5 апреля 2014 г.

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

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



Превращает 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("http://ift.tt/1jfagxN")
.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


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


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий