All Projects → tslamic → jokster

tslamic / jokster

Licence: other
A demo app used for Dagger2 workshops.

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to jokster

Istheapp
Open-source android spyware
Stars: ✭ 186 (+1140%)
Mutual labels:  dagger2
Nobullshit
A sample project entirely written in Kotlin. Backend/Frontend with Ktor and Android app.
Stars: ✭ 221 (+1373.33%)
Mutual labels:  dagger2
Vigilante
🛡️ Android security (camera/microphone dots indicators) app using Hilt, Animations, Coroutines, Material, StateFlow, Jetpack (Room, ViewModel, Paging, Security, Biometrics, Start-up) based on MVVM architecture.
Stars: ✭ 234 (+1460%)
Mutual labels:  dagger2
Androidcourse101
Complete Android Development Course 101: Spotify Clone App
Stars: ✭ 208 (+1286.67%)
Mutual labels:  dagger2
Mvvmframe
🏰 MVVMFrame for Android 是一个基于Google官方推出的Architecture Components dependencies(现在叫JetPack){ Lifecycle,LiveData,ViewModel,Room } 构建的快速开发框架。有了MVVMFrame的加持,从此构建一个MVVM模式的项目变得快捷简单。
Stars: ✭ 218 (+1353.33%)
Mutual labels:  dagger2
Wanandroid
WanAndroid客户端,项目基于 Material Design + MVP +dagger2 + RxJava + Retrofit + Glide + greendao 等架构进行设计实现,极力打造一款 优秀的玩Android https://www.wanandroid.com 客户端,是一个不错的Android应用开发学习参考项目
Stars: ✭ 223 (+1386.67%)
Mutual labels:  dagger2
Android Audiorecorder App
Android application to record audio. RxJava2, Dagger2, MVP, RoomDb.
Stars: ✭ 180 (+1100%)
Mutual labels:  dagger2
Multimodulegithubclient
Example multi-module Android project with unit tests, dagger 2, test coverage and others
Stars: ✭ 244 (+1526.67%)
Mutual labels:  dagger2
Flyabbit
🔥组件化,Retrofit,Rxjava2,dagger2,Mvp ,ReactNative ,Atlas(插件化)
Stars: ✭ 219 (+1360%)
Mutual labels:  dagger2
Android Mvvm Architecture
This repository contains a detailed sample app that implements MVVM architecture using Dagger2, Room, RxJava2, FastAndroidNetworking and PlaceholderView
Stars: ✭ 2,720 (+18033.33%)
Mutual labels:  dagger2
Dahaka
Demo project for Dagger 2
Stars: ✭ 210 (+1300%)
Mutual labels:  dagger2
Awesome Wanandroid
⚡致力于打造一款极致体验的 http://www.wanandroid.com/ 客户端,知识和美是可以并存的哦QAQn(*≧▽≦*)n
Stars: ✭ 2,525 (+16733.33%)
Mutual labels:  dagger2
Bubbble
Sample app showcases the MVP pattern and Robert Martin's Clean Architecture approach.
Stars: ✭ 226 (+1406.67%)
Mutual labels:  dagger2
Android References
👏 Android 示例程序:MVP, MVVM, 组件化, AndroidX, ARouter, RxJava, EventBus, ButterKnife, 视频播放, 视频直播, 网络访问, 布局和控件整理等
Stars: ✭ 206 (+1273.33%)
Mutual labels:  dagger2
Movies Kotlin Kata
Katas for practice Kotlin( Coroutines, dataclasses, delegate properties...) Clean Architecture and best practices in Android(DI, Dagger, MVP, Espresso) implemented by Jorge Sánchez (Xurxodev)
Stars: ✭ 240 (+1500%)
Mutual labels:  dagger2
Searchbubble
A bubble to do your search.
Stars: ✭ 181 (+1106.67%)
Mutual labels:  dagger2
Movieguide Kotlin
Movie discovery app showcasing Kotlin, RxJava, Dagger2, MVP using Clean Architecture
Stars: ✭ 222 (+1380%)
Mutual labels:  dagger2
android-mvp-kotlin
使用kotlin实现Android MVP模式,使用了Dagger2、Retrofit、RxJava等
Stars: ✭ 14 (-6.67%)
Mutual labels:  dagger2
Dagger Examples
Some dagger-android examples with Retrofit2, MVVM architecture, RxJava, (Java)
Stars: ✭ 242 (+1513.33%)
Mutual labels:  dagger2
Movieguide
Movie discovery app showcasing MVP, RxJava, Dagger 2 and Clean Architecture
Stars: ✭ 2,573 (+17053.33%)
Mutual labels:  dagger2

Jokster App 👺

A simple joke-telling app demonstrating the very basics of Dagger2. 🗡️

Motivation

Dependency injection or DI is a 25-dollar term for a 5-cent concept. It means giving an object its instance variables. So instead of e.g. creating an OkHttpClient instance yourself:

class ChuckApi {
  private val client = OkHttpClient()
  // ...
}

inject it via a constructor:

class ChuckApi(private val client: OkHttpClient) { 
 // ...
}

Voilà! You just performed a dependency injection. Simple, right?

One of the cornerstones of object-oriented design is the Dependency inversion principle. In essence, it focuses on what the code does, and not how it does it. Consider the following class:

class ChuckApi {
  fun tellJoke(): String {
    // returns a funny joke from the interwebs
  }
}

If another class relies on the ChuckApi, such as:

class Repo(private val api: ChuckApi) {
 // ...
}

then any changes to the ChuckApi most likely affect the Repo, too. Also, assuming ChuckApi requires a network connection, Repo might be difficult to test. Introducing an interface such as:

interface FunnyApi {
  fun tellJoke(): String
}

and having ChuckApi implement it:

class ChuckApi : FunnyApi {
  override fun tellJoke(): String {
    // same as before
  }
}

but making the Repo depend on the interface, rather than a concrete class:

class Repo(private val api: FunnyApi) {
 // heavy use of the api here ...
}

gives us the ability to pass Repo any implementation of the FunnyApi interface. This makes testing easier and ensures Repo needs no code changes if various FunnyApi implementations are provided.

So, how do we pass FunnyApi instances to the Repo class? You guessed it - it's with dependency injection!

A vague intro to Dagger2

Dagger2 is a popular DI framework for Java, Kotlin and Android. To use it, first add it to the list of your dependencies in build.gradle:

dependencies {
  implementation 'com.google.dagger:dagger:2.x'
  annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
}

When using Kotlin, use kapt instead:

apply plugin: 'kotlin-kapt'

dependencies {
  implementation 'com.google.dagger:dagger:2.x'
  kapt 'com.google.dagger:dagger-compiler:2.x'
}

To provide dependencies, you need modules. Modules are classes with the @Module annotation, and methods annotated with @Provides:

@Module  
class NetworkModule {  
    @Provides fun providesHttpClient(): OkHttpClient = OkHttpClient()
}

Dagger will inspect the class, look at the return types of the annotated methods, and say: I now know how to create these objects!

Another method might need an OkHttpClient to create a dependency:

@Module  
class ApiModule {  
    @Provides fun providesFunnyApi(c: OkHttpClient): FunnyApi = ChuckApi(c)
}

Assuming Dagger knows about the NetworkModule, it knows how to create the OkHttpClient and therefore knows how to create an instance of FunnyApi. In cases where Dagger can infer all the necessary dependencies, you can use a shorter @Binds annotation:

@Module  
interface ApiModule {  
    // Equivalent to the ApiModule above, just shorter. 
    @Binds fun providesFunnyApi(api: ChuckApi): FunnyApi
}

To let Dagger create objects on your behalf, you need to add an @Inject annotation to your constructors:

class ChuckApi @Inject constructor(c: OkHttpClient) : FunnyApi {  
    // ...
}

Components stitch multiple modules together:

@Component(  
    modules = [  
        NetworkModule::class,  
        ApiModule::class  
  ]  
)  
interface AppComponent {  
    fun inject(activity: MainActivity)
    fun client(): OkHttpClient
}

Note the @Component annotation, along with the list of modules it includes.

Dagger will generate a class called DaggerAppComponent implementing the AppComponent interface. To consume the dependencies, you need a DaggerAppComponent instance, which is typically created in an Application class:

class App : Application() {  
    private lateinit var component: AppComponent  
  
    override fun onCreate() {  
        super.onCreate()  
        component = DaggerAppComponent.builder()  
            .networkModule(NetworkModule())  
            .apiModule(ApiModule())  
            .build()  
    }
  
    fun component(): AppComponent = component  
}

You're now ready to consume dependencies. There are two ways to do it.

  1. Use an @Inject annotation:
class MainActivity : AppCompatActivity() {  
    @Inject lateinit var factory: JokerViewModel.Factory  
  
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  

        // get the AppComponent instance, and invoke the 
        // appropriate inject method which will automatically
        // populate all @Inject fields.
        val component = (application as App).component()  
        component.inject(this)
    }
}

Note that the inject method is not magical, nor special. The name is merely a convention, we could easily call it awesomeMethod4Realz. The important bit is the parameter - MainActivity. Dagger will generate a class that knows how to populate all @Inject fields, and whenever component.inject(this) is invoked, the call will be propagated to a method looking like this:

public static void injectFactory(MainActivity instance, JokerViewModel.Factory factory) {  
  instance.factory = factory;  
}

As you may have guessed, the JokerViewModel.Factory is created and provided by Dagger.

  1. Call the appropriate accessor methods:
class MainActivity : AppCompatActivity() {    
    override fun onCreate(savedInstanceState: Bundle?) {  
        super.onCreate(savedInstanceState)  

        // get the AppComponent instance and invoke the getter.
        val component = (application as App).component()  
        val client = component.client()
    }
}

Use this repo to play around with Dagger2, and check out these links to learn more:

License

Copyright © 2019 tslamic
This work is free. You can redistribute it and/or modify it under the
terms of the Do What The Fuck You Want To Public License, Version 2,
as published by Sam Hocevar.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].