Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Retrofit + RxJava + Retrolambda

Retrofit + RxJava + Retrolambda

Apresentação realizada no 7º JUG Vale

Rafael Toledo

October 25, 2014
Tweet

More Decks by Rafael Toledo

Other Decks in Programming

Transcript

  1. Integração REST •  Praticamente nenhum app funciona isoladamente •  Integração

    com APIs é essencial •  Eficiência é um requisito, sempre!
  2. REST de Referência https://api.example.com GET - /product /product/1 /product?name=? POST

    - /product (json no corpo) PUT - /product/1 (json no corpo) DELETE - /product/1
  3. Product JSON { "id": 55041 "name": "Biscoito (ou bolacha?) Recheado",

    "categories-array": [ "doce", "biscoito", "bolacha" ], "description": "...", "permalink": "http://example.com/product/55041", }
  4. Método 1 - Apache HttpClient final String ENDPOINT = "https://api.example.com";

    HttpClient client = DefaultHttpClient.getInstance(); HttpGet get = new HttpGet(ENDPOINT + "/product"); HttpResponse response = client.execute(get); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { String raw = EntityUtils.toString(response.getEntity(), "UTF-8"); JSONArray json = new JSONArray(raw); for (int i = 0; i < json.length(); i++) { Product product = new Product(); product.setName(json.getJSONObject(i).getString("name")); product.setId(json.getJSONObject(i).getLong("id")); ...
  5. Agravante Uso de AsyncTasks, Services ou WorkerThreads Gerenciar a request

    em uma thread separada / atualizar a UI na main thread
  6. Método 1A - OkHttp Apache Wrapper HttpClient client = new

    OkApacheClient(); HttpGet get = new HttpGet(ENDPOINT + "/product"); HttpResponse response = client.execute(get); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { String raw = EntityUtils.toString(response.getEntity(), "UTF-8"); JSONArray json = new JSONArray(raw); for (int i = 0; i < json.length(); i++) { Product product = new Product(); product.setName(json.getJSONArray(i).getString("name")); ... }
  7. Dependências // build.gradle do módulo do app ... dependencies {

    ... compile 'com.squareup.okhttp:okhttp-apache:2.0.+' }
  8. Método 2 - OkHttp OkHttpClient client = new OkHttpClient(); Request

    request = new Request.Builder() .url(ENDPOINT + "/product").build(); Response response = client.newCall(request).execute(); String raw = response.body().string(); JSONArray json = new JSONArray(raw); ...
  9. Dependências // build.gradle do módulo do app ... dependencies {

    ... compile 'com.squareup.okhttp:okhttp:2.0.+' }
  10. Método 2A - OkHttp + Gson public class Product {

    private String name; @SerializedName("categories-array") private List<String> categoriesArray; ... }
  11. Método 2A - OkHttp + Gson OkHttpClient client = new

    OkHttpClient(); Request request = new Request.Builder() .url(ENDPOINT + "/product").build(); Response response = client.newCall(request).execute(); String raw = response.body().string(); JSONArray json = new JSONArray(raw); Gson gson = new Gson(); for (int i = 0; i < json.length(); i++) { Product product = gson .fromJson(json.getJSONObject(i).toString(), Product.class); ... }
  12. Método 2A - OkHttp + Gson OkHttpClient client = new

    OkHttpClient(); Request request = new Request.Builder() .url(ENDPOINT + "/product").build(); Response response = client.newCall(request).execute(); String raw = response.body().string(); Type listType = new TypeToken<List<Product>>{}.getType(); List<Product> products = new Gson().fromJson(raw, listType);
  13. Dependências // build.gradle do módulo do app ... dependencies {

    ... compile 'com.squareup.okhttp:okhttp:2.0.+' compile 'com.google.code.gson:gson:2.3' }
  14. Método 3 - Retrofit public interface ExampleService { @GET("/product") List<Product>

    getProducts(); @POST("/product") void saveProduct(@Body Product product); @PUT("/product/{id}") void updateProduct(@Path("id") long id, @Body Product product); @DELETE("/product/{id}") void deleteProduct(@Path("id") long id); }
  15. Método 3 - Retrofit public interface ExampleService { @GET("/product/{id}") Product

    getProduct(@Path("id") long id); @GET("/product") Product getProductByName(@Query("name") String name); }
  16. Método 3 - Retrofit public class ExampleApi { private static

    ExampleService instance; public static ExampleService getInstance() { if (instance == null) { RestAdapter adapter = new RestAdapter.Builder() .setEndpoint("https://api.example.com") .build(); instance = adapter.create(ExampleService.class); } return instance; } }
  17. Método 3A - Retrofit com Callbacks public interface ExampleService {

    @GET("/product") List<Product> getProducts(); // ...modificamos para... @GET("/product") void getProducts(Callback<List<Product>> callback);
  18. Método 3A - Retrofit com Callbacks E pronto! ExampleApi.getInstance().getProduct(1, new

    Callback<Product>() { @Override public void success(Product product, Response response) {} @Override public void failure(RetrofitError error) {} });
  19. Vantagens Gerenciado automaticamente para os callbacks serem executados na UI

    Dispensa o tratamento de exceptions na request (método failure)
  20. Dependências // build.gradle do módulo do app ... dependencies {

    ... compile 'com.squareup.okhttp:okhttp:2.0.+' compile 'com.squareup.retrofit:retrofit:1.7.+' }
  21. Por que melhorar mais ainda? •  Verbosidade •  Código macarrônico

    •  Bagunça de código com chamadas encadeadas •  Muitas classes anônimas
  22. RxJava Programação Funcional Reativa no Java É uma das grandes

    febres no Open Source Android hoje Ganhou mais fama ainda por causa do port Android feito pela Netflix
  23. Método 4 - Retrofit e RxJava public interface ExampleService {

    @GET("/product/{id}") void getProduct(@Path("id") long id, Callback<Product> callback); // ...modificamos para... @GET("/product/{id}") Observable<Product> getProduct(@Path("id") long id);
  24. Método 4 - Retrofit e RxJava ExampleApi.getInstance().getProduct(1).subscribe(onSuccess, onError); protected Action1<Product>

    onSuccess = new Action1<Product>() { @Override public void call(Product product) {} }; protected Action1<Throwable> onError = new Action1<Throwable>() { @Override public void call(Throwable error) {} };
  25. Dependências // build.gradle do módulo do app ... dependencies {

    ... compile 'com.squareup.okhttp:okhttp:2.0.+' compile 'com.squareup.retrofit:retrofit:1.7.+' compile 'com.netflix.rxjava:rxjava-android:0.20.+' }
  26. Qual a necessidade disso? •  Chamada mais limpa e clara

    •  Maior coesão no tratamento de erro / sucesso •  Se o tratamento for comum a todas as Activities / Fragments, você pode criar a implementação comum e estender :)
  27. Retrolambda Porque o Java 5/6/7 não poderia ficar de fora!

    https://github.com/orfjackal/retrolambda Traz ao Java 5/6/7 uma das mais poderosas características do Java 8: o uso de lambdas!
  28. Retrolambda Como o Java do Android é o 6 e

    7 (full, a partir do Kitkat), precisávamos disso! https://github.com/evant/gradle-retrolambda
  29. Retrolambda - Como Usar // no build.gradle principal buildscript {

    dependencies { classpath 'com.android.tools.build:gradle:0.13.3' classpath 'me.tatarka:gradle-retrolambda:2.4.0' } }
  30. Retrolambda - Como Usar // no build.gradle do projeto apply

    plugin: 'com.android.application' apply plugin: 'retrolambda' android { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
  31. Método 4 - Sem Retrolambda ExampleApi.getInstance().getProduct(1).subscribe(onSuccess, onError); protected Action1<Product> onSuccess

    = new Action1<Product>() { @Override public void call(Product product) {} }; protected Action1<Throwable> onError = new Action1<Throwable>() { @Override public void call(Throwable error) {} };
  32. Método 5 - Com Retrolambda protected Action1<Throwable> onError = error

    -> { dialog.dismiss(); }; protected Action1<Throwable> onError = error -> dialog.dismiss();