quem sou eu? - rafael .quem sou eu? rafael toledo dev java / android

Download Quem sou eu? - Rafael  .Quem sou eu? Rafael Toledo Dev Java / Android

Post on 24-Dec-2018

214 views

Category:

Documents

0 download

Embed Size (px)

TRANSCRIPT

Quem sou eu? Rafael Toledo Dev Java / Android www.rafaeltoledo.net

Integrao REST Praticamente nenhum app funciona

isoladamente Integrao com APIs essencial Eficincia um requisito, sempre!

Material Necessrio

Material Necessrio

Material Necessrio

Material Necessrio Tesoura Sem Ponta (para no se machucar)

REST de Referncia https://api.example.com GET - /product /product/1 /product?name=? POST - /product (json no corpo) PUT - /product/1 (json no corpo) DELETE - /product/1

Product JSON { "id": 55041 "name": "Biscoito (ou bolacha?) Recheado", "categories-array": [ "doce", "biscoito", "bolacha" ], "description": "...", "permalink": "http://example.com/product/55041", }

Mtodo 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")); ...

Agravante Uso de AsyncTasks, Services ou WorkerThreads Gerenciar a request em uma thread separada / atualizar a UI na main thread

OkHttp http://square.github.io/okhttp SPDY/HTTP GZIP transparente Gerenciamento de Cache Recover automtico em caso de falhas de rede

Mtodo 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")); ... }

Dependncias // build.gradle do mdulo do app ... dependencies { ... compile 'com.squareup.okhttp:okhttp-apache:2.0.+' }

Mtodo 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); ...

Dependncias // build.gradle do mdulo do app ... dependencies { ... compile 'com.squareup.okhttp:okhttp:2.0.+' }

Mtodo 2A - OkHttp + Gson public class Product { private String name; @SerializedName("categories-array") private List categoriesArray; ... }

Mtodo 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); ... }

Mtodo 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{}.getType(); List products = new Gson().fromJson(raw, listType);

Dependncias // build.gradle do mdulo do app ... dependencies { ... compile 'com.squareup.okhttp:okhttp:2.0.+' compile 'com.google.code.gson:gson:2.3' }

Retrofit http://square.github.io/retrofit Transforma o seu REST em uma interface! Integrao com o OkHttp (classpath)

Mtodo 3 - Retrofit public interface ExampleService { @GET("/product") List 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); }

Mtodo 3 - Retrofit public interface ExampleService { @GET("/product/{id}") Product getProduct(@Path("id") long id); @GET("/product") Product getProductByName(@Query("name") String name); }

Mtodo 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; } }

Mtodo 3 - Retrofit E pronto! Product product = ExampleApi.getInstance().getProduct(1);

Porm Ainda depende do uso de AsyncTasks, Services ou WorkerThreads

Mtodo 3A - Retrofit com Callbacks public interface ExampleService { @GET("/product") List getProducts(); // ...modificamos para... @GET("/product") void getProducts(Callback callback);

Mtodo 3A - Retrofit com Callbacks E pronto! ExampleApi.getInstance().getProduct(1, new Callback() { @Override public void success(Product product, Response response) {} @Override public void failure(RetrofitError error) {} });

Vantagens Gerenciado automaticamente para os callbacks serem executados na UI Dispensa o tratamento de exceptions na request (mtodo failure)

Dependncias // build.gradle do mdulo do app ... dependencies { ... compile 'com.squareup.okhttp:okhttp:2.0.+' compile 'com.squareup.retrofit:retrofit:1.7.+' }

Calma!!! ainda pode melhorar...

Por que melhorar mais ainda? Verbosidade Cdigo macarrnico Baguna de cdigo com chamadas

encadeadas Muitas classes annimas

RxJava Programao 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

RxJava http://github.com/ReactiveX/RxJava Retrofit compatvel com RxJava! http://blog.danlew.net/ - Blog do GDE Dan Lew, com uma srie de 4 tutoriais sobre RxJava

Mtodo 4 - Retrofit e RxJava public interface ExampleService { @GET("/product/{id}") void getProduct(@Path("id") long id, Callback callback); // ...modificamos para... @GET("/product/{id}") Observable getProduct(@Path("id") long id);

Mtodo 4 - Retrofit e RxJava ExampleApi.getInstance().getProduct(1).subscribe(onSuccess, onError); protected Action1 onSuccess = new Action1() { @Override public void call(Product product) {} }; protected Action1 onError = new Action1() { @Override public void call(Throwable error) {} };

Dependncias // build.gradle do mdulo 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.+' }

Qual a necessidade disso? Chamada mais limpa e clara Maior coeso no tratamento de erro /

sucesso Se o tratamento for comum a todas as

Activities / Fragments, voc pode criar a implementao comum e estender :)

Calma a!!! E como fica o controle na thread de UI?

J testei e deu pau!

Mtodo 4 - Retrofit e RxJava ExampleApi.getInstance().getProduct(1) .observeOn(AndroidSchedulers.mainThread()) .subscribe(onSuccess, onError);

Apesar de bacana... Ainda temos o problema da

"verbosidade" do Java

Retrolambda Porque o Java 5/6/7 no poderia ficar de fora! https://github.com/orfjackal/retrolambda Traz ao Java 5/6/7 uma das mais poderosas caractersticas do Java 8: o uso de lambdas!

Retrolambda Como o Java do Android o 6 e 7 (full, a partir do Kitkat), precisvamos disso! https://github.com/evant/gradle-retrolambda

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' } }

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 } }

Mtodo 4 - Sem Retrolambda ExampleApi.getInstance().getProduct(1).subscribe(onSuccess, onError); protected Action1 onSuccess = new Action1() { @Override public void call(Product product) {} }; protected Action1 onError = new Action1() { @Override public void call(Throwable error) {} };

Mtodo 5 - Com Retrolambda ExampleApi.getInstance().getProduct(1).subscribe(onSuccess, onError); protected Action1 onSuccess = product -> { }; protected Action1 onError = error -> { };

Mtodo 5 - Com Retrolambda protected Action1 onError = error -> { dialog.dismiss(); }; protected Action1 onError = error -> dialog.dismiss();

Obrigado! www.rafaeltoledo.net