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

Unconventional Android v3

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

Unconventional Android v3

Avatar for Richard Cirerol

Richard Cirerol

March 19, 2016
Tweet

More Decks by Richard Cirerol

Other Decks in Programming

Transcript

  1. Why "(Un)conventional"? 4 Deviate from the traditional Google conventions 4

    No Fragments, Loaders, or AsyncTasks 4 Strict about Android code vs Java code 4 Use patterns and conventions Unconventional Android v3 | Richard Cirerol | @codeprogression
  2. Dependency Injection 4 Dagger 4 Glassfish annotation 4 Android APT

    plugin Unconventional Android v3 | Richard Cirerol | @codeprogression
  3. Code Generation 4 Lombok 4 Parceler 4 ParcelablePlease 4 AutoValue/AutoParcel

    Unconventional Android v3 | Richard Cirerol | @codeprogression
  4. UI 4 Picasso 4 Butterknife 4 Android Data Binding Unconventional

    Android v3 | Richard Cirerol | @codeprogression
  5. Other 4 Timber 4 Joda Time (for Android) 4 Reactive

    Extensions (RxJava/RxAndroid) Unconventional Android v3 | Richard Cirerol | @codeprogression
  6. TMDB 4 Similar to IMDB 4 Free access 4 Open,

    documented API Unconventional Android v3 | Richard Cirerol | @codeprogression
  7. Networking 1. Define types 2. Configure deserialization rules 3. Define

    web API methods 4. Provide API service bridge 5. Use ReactiveX Unconventional Android v3 | Richard Cirerol | @codeprogression
  8. Configuration { "images":{ "base_url": "...", "secure_base_url": "...", ... }, "change_keys":[]

    } Unconventional Android v3 | Richard Cirerol | @codeprogression
  9. public class Configuration { private Images images; private List<String> changeKeys;

    } Unconventional Android v3 | Richard Cirerol | @codeprogression
  10. Lombok Reduce boilerplate code 4 @Getter 4 @Setter 4 @EqualsAndHashCode

    4 @ToString 4 @Data Unconventional Android v3 | Richard Cirerol | @codeprogression
  11. public class Configuration { @Getter private Images images; private List<String>

    changeKeys; } Unconventional Android v3 | Richard Cirerol | @codeprogression
  12. GSON Mapping field names // base_url -> baseUrl Gson gson

    = new GsonBuilder() .setFieldNamingPolicy( FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .create(); Unconventional Android v3 | Richard Cirerol | @codeprogression
  13. Retrofit 4 Define a API service via interface and annotations

    4 HttpClient (OkHttp) 4 Converter (Gson) 4 Optional adapter (RxJava) Unconventional Android v3 | Richard Cirerol | @codeprogression
  14. Define the API public interface TmdbApi { @GET("configuration") Observable<Configuration> getConfiguration();

    @GET("movie/now_playing") Observable<Movie.Collection> getNowPlaying(); @GET("movie/{id}") Observable<Movie> getMovie(@Path("id") long id); } Unconventional Android v3 | Richard Cirerol | @codeprogression
  15. Configure the API TmdbApi apiService(OkHttpClient.Builder client, GsonBuilder gson) { client.addInterceptor(getApiKeyInterceptor());

    Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.themoviedb.org/3/") .client(client.build()) .addConverterFactory(GsonConverterFactory.create(gson.create())) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); return retrofit.create(TmdbApi.class); } Unconventional Android v3 | Richard Cirerol | @codeprogression
  16. Add api_key query parameter to every call via OkHttp interceptor

    private Interceptor getApiKeyInterceptor() { return new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); HttpUrl url = request.url().newBuilder() .addQueryParameter("api_key", BuildConfig.TMDB_API_KEY).build(); request = request.newBuilder().url(url).build(); return chain.proceed(request); } }; } Unconventional Android v3 | Richard Cirerol | @codeprogression
  17. Provide an API service bridge 4 Hides naked API definition

    from consumers 4 Allows for further customization 4 May look similar to the Retrofit interface, but... 4 Service/API interfaces can vary independently Unconventional Android v3 | Richard Cirerol | @codeprogression
  18. Provide an API service bridge private TmdbApi api; public Observable<Movie.Collection>

    getMovies() { return api.getMovies() .subscribeOn(Schedulers.io()); } Unconventional Android v3 | Richard Cirerol | @codeprogression
  19. Dagger 2.x 4 Dependency injection without reflection 4 Define and

    construct dependencies 4 Inject dependencies 4 Keep dependency consumers ignorant. Unconventional Android v3 | Richard Cirerol | @codeprogression
  20. Dagger 4 @Inject 4 @Scope 4 @Qualifier / @Named 4

    @Module / @Provides 4 @Component / @Subcomponent Unconventional Android v3 | Richard Cirerol | @codeprogression
  21. @Inject 4 Denotes field to be injected 4 Denotes constructor

    with parameters to be injected Unconventional Android v3 | Richard Cirerol | @codeprogression
  22. @Inject TmdbService service; @Inject public TmdbService(TmdbApi api) { this.api =

    api; } Unconventional Android v3 | Richard Cirerol | @codeprogression
  23. @Scope annotations 4 Defines the lifetime of the dependency 4

    @Singleton (Application singleton) 4 @PerActivity (Activity singleton) 4 No-scope == new type per injection Unconventional Android v3 | Richard Cirerol | @codeprogression
  24. @Singleton public class TmdbService{ private final TmdbApi api; @Inject public

    TmdbService(TmdbApi api) { this.api = api; } } Unconventional Android v3 | Richard Cirerol | @codeprogression
  25. @Provides annotations 4 Denotes methods that construct dependencies 4 Always

    in a @Module class 4 Usually accompanied by a @Scope Unconventional Android v3 | Richard Cirerol | @codeprogression
  26. @Component 4 Interface to wire up providers to consumers 4

    Defines inject methods 4 Defines exportable dependencies 4 Uses modules and scoped classes 4 Can declare parent components Unconventional Android v3 | Richard Cirerol | @codeprogression
  27. @Singleton @Component(modules = { ApplicationModule.class, TmdbApiModule.class }) public interface ApplicationComponent

    { ... TmdbService service(); void inject(LauncherActivity launcherActivity); } Unconventional Android v3 | Richard Cirerol | @codeprogression
  28. @PerActivity @Component(dependencies = ApplicationComponent.class, includes = { ActivityModule.class }) public

    interface MainActivityComponent { void inject(MoviesView moviesView); void inject(MovieItemView movieItemView); } Unconventional Android v3 | Richard Cirerol | @codeprogression
  29. What does Dagger do with all this? 4 Writes code!

    Unconventional Android v3 | Richard Cirerol | @codeprogression
  30. Model-View-Presenter 4 Defines distinct responsibilities 4 View notifies the presenter

    of events 4 Presenter delegates work to a service (the model) 4 Presenter updates the view with results from the model Unconventional Android v3 | Richard Cirerol | @codeprogression
  31. MVP - Passive View Updating the view: - Define a

    view interface - Implement the interface in your custom view - Instrument the view from the presenter Unconventional Android v3 | Richard Cirerol | @codeprogression
  32. MVP - Passive View Conventions: - Inject the presenter -

    On load, attach the view (interface) to the presenter - On unload, detach the view from the presenter - While attached, delegate work and update the view Unconventional Android v3 | Richard Cirerol | @codeprogression
  33. MVP - Android Data Binding Updating the view: - Define

    a view model - Use view model variables in your layout markup - Instrument the view model from the presenter Unconventional Android v3 | Richard Cirerol | @codeprogression
  34. Configure Android Data Binding 4 Enable in gradle 4 Wrap

    view in <layout/> 4 Add <data/> and <variable/> elements 4 Bind variables Unconventional Android v3 | Richard Cirerol | @codeprogression
  35. MVP - Android Data Binding Conventions: - Inject the presenter

    - Create the view model object - On load, attach the view model to the presenter - On unload, detach the view model from the presenter - While attached, delegate work and update the view model Unconventional Android v3 | Richard Cirerol | @codeprogression
  36. Android Data Binding 4 Define your own binding adapters (custom

    attributes) 4 Use conditional logic in the layout Unconventional Android v3 | Richard Cirerol | @codeprogression
  37. Thanks! Richard Cirerol @codeprogression http://codeprogression.com Come back for RxAndroid after

    lunch! Unconventional Android v3 | Richard Cirerol | @codeprogression