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

Unconventional Android v3

Unconventional Android v3

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