diff --git a/app/build.gradle b/app/build.gradle index 64cfb69..12833c9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -78,5 +78,7 @@ dependencies { testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-inline:2.11.0' + + implementation "android.arch.lifecycle:extensions:1.0.0" } diff --git a/app/src/main/java/uk/co/mycompany/di/ActivityBuilder.kt b/app/src/main/java/uk/co/mycompany/di/ActivityBuilder.kt index d1b3648..eb4d52e 100644 --- a/app/src/main/java/uk/co/mycompany/di/ActivityBuilder.kt +++ b/app/src/main/java/uk/co/mycompany/di/ActivityBuilder.kt @@ -3,11 +3,10 @@ package uk.co.mycompany.di import dagger.Module import dagger.android.ContributesAndroidInjector import uk.co.mycompany.ui.main.MainActivity -import uk.co.mycompany.ui.main.di.MainActivityModule @Module abstract class ActivityBuilder { - @ContributesAndroidInjector(modules = arrayOf(MainActivityModule::class)) + @ContributesAndroidInjector abstract fun bindMainActivity(): MainActivity } \ No newline at end of file diff --git a/app/src/main/java/uk/co/mycompany/di/AppModule.kt b/app/src/main/java/uk/co/mycompany/di/AppModule.kt index 5685c83..b0d8a69 100644 --- a/app/src/main/java/uk/co/mycompany/di/AppModule.kt +++ b/app/src/main/java/uk/co/mycompany/di/AppModule.kt @@ -15,13 +15,14 @@ import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import uk.co.mycompany.api.ApiService +import uk.co.mycompany.ui.main.di.ViewModelModule import uk.co.mycompany.util.SchedulerProvider import java.io.File import java.util.* import java.util.concurrent.TimeUnit import javax.inject.Singleton -@Module +@Module(includes = arrayOf(ViewModelModule::class)) class AppModule { @Provides diff --git a/app/src/main/java/uk/co/mycompany/ui/main/MainActivity.kt b/app/src/main/java/uk/co/mycompany/ui/main/MainActivity.kt index 0eb612a..4a02899 100644 --- a/app/src/main/java/uk/co/mycompany/ui/main/MainActivity.kt +++ b/app/src/main/java/uk/co/mycompany/ui/main/MainActivity.kt @@ -1,29 +1,45 @@ package uk.co.mycompany.ui.main +import android.app.Fragment +import android.arch.lifecycle.ViewModelProvider +import android.arch.lifecycle.ViewModelProviders import android.os.Bundle +import android.support.v7.app.AppCompatActivity import android.util.Log -import dagger.android.DaggerActivity +import dagger.android.* import io.reactivex.disposables.CompositeDisposable import io.reactivex.rxkotlin.subscribeBy +import kotlinx.android.synthetic.main.activity_main.* import uk.co.mycompany.R import javax.inject.Inject -class MainActivity: DaggerActivity() { +class MainActivity: AppCompatActivity(), HasFragmentInjector { + + @Inject lateinit var fragmentInjector: DispatchingAndroidInjector + + override fun fragmentInjector(): AndroidInjector { + return fragmentInjector + } private val compositeDisposable by lazy { CompositeDisposable() } - @Inject lateinit var mainActivityViewModel: MainActivityViewModel + lateinit var mainActivityViewModel: MainActivityViewModel + @Inject lateinit var viewModelFactory: ViewModelFactory override fun onCreate(savedInstanceState: Bundle?) { + AndroidInjection.inject(this) super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + mainActivityViewModel = ViewModelProviders.of(this, viewModelFactory).get(MainActivityViewModel::class.java) compositeDisposable.add(mainActivityViewModel.showDataFromApi() .subscribeBy(onSuccess = { Log.d("MainActivity", it.ip) + tv.text = it.ip }, onError = { Log.d("MainActivity", it.message) + tv.text = it.message })) } diff --git a/app/src/main/java/uk/co/mycompany/ui/main/MainActivityViewModel.kt b/app/src/main/java/uk/co/mycompany/ui/main/MainActivityViewModel.kt index 052344a..a6356a1 100644 --- a/app/src/main/java/uk/co/mycompany/ui/main/MainActivityViewModel.kt +++ b/app/src/main/java/uk/co/mycompany/ui/main/MainActivityViewModel.kt @@ -1,11 +1,14 @@ package uk.co.mycompany.ui.main +import android.arch.lifecycle.ViewModel import io.reactivex.Single import uk.co.mycompany.api.model.IpAddress import uk.co.mycompany.repository.Repository import uk.co.mycompany.util.SchedulerProvider +import javax.inject.Inject -class MainActivityViewModel(private val repository: Repository, private val schedulerProvider: SchedulerProvider) { +open class MainActivityViewModel +@Inject constructor(private val repository: Repository, private val schedulerProvider: SchedulerProvider) :ViewModel(){ fun showDataFromApi(): Single = repository.getDataFromApi() .compose(schedulerProvider.getSchedulersForSingle()) diff --git a/app/src/main/java/uk/co/mycompany/ui/main/ViewModelFactory.kt b/app/src/main/java/uk/co/mycompany/ui/main/ViewModelFactory.kt new file mode 100644 index 0000000..7792e1e --- /dev/null +++ b/app/src/main/java/uk/co/mycompany/ui/main/ViewModelFactory.kt @@ -0,0 +1,45 @@ +package uk.co.mycompany.ui.main + +import android.arch.lifecycle.ViewModel +import android.arch.lifecycle.ViewModelProvider +import android.util.Log +import javax.inject.Inject +import javax.inject.Provider +import javax.inject.Singleton + +/** + * Created by Md. Sifat-Ul Haque on 1/29/2018. + */ +@Singleton +open class ViewModelFactory +@Inject constructor(private val creators: Map, @JvmSuppressWildcards Provider>) : ViewModelProvider.Factory { + + init { + Log.d(TAG, "ViewModelFactory: ") + } + + override fun create(modelClass: Class): T { + var creator: Provider? = creators[modelClass] + if (creator == null) { + for ((key, value) in creators) { + if (modelClass.isAssignableFrom(key)) { + creator = value + break + } + } + } + if (creator == null) { + throw IllegalArgumentException("unknown model class " + modelClass) + } + try { + return creator.get() as T + } catch (e: Exception) { + throw RuntimeException(e) + } + + } + + companion object { + private val TAG = "ViewModelFactory" + } +} \ No newline at end of file diff --git a/app/src/main/java/uk/co/mycompany/ui/main/ViewModelKey.kt b/app/src/main/java/uk/co/mycompany/ui/main/ViewModelKey.kt new file mode 100644 index 0000000..8bde598 --- /dev/null +++ b/app/src/main/java/uk/co/mycompany/ui/main/ViewModelKey.kt @@ -0,0 +1,16 @@ +package uk.co.mycompany.ui.main + +import android.arch.lifecycle.ViewModel + +import dagger.MapKey +import kotlin.annotation.Retention +import kotlin.reflect.KClass + +/** + * Created by Md. Sifat-Ul Haque on 1/29/2018. + */ +@MustBeDocumented +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.RUNTIME) +@MapKey +annotation class ViewModelKey(val value: KClass) \ No newline at end of file diff --git a/app/src/main/java/uk/co/mycompany/ui/main/di/MainActivityModule.kt b/app/src/main/java/uk/co/mycompany/ui/main/di/MainActivityModule.kt index 6904075..f297837 100644 --- a/app/src/main/java/uk/co/mycompany/ui/main/di/MainActivityModule.kt +++ b/app/src/main/java/uk/co/mycompany/ui/main/di/MainActivityModule.kt @@ -8,7 +8,6 @@ import uk.co.mycompany.util.SchedulerProvider @Module class MainActivityModule { - @Provides fun provideViewModel(repository: Repository, schedulerProvider: SchedulerProvider) = MainActivityViewModel(repository, schedulerProvider) } \ No newline at end of file diff --git a/app/src/main/java/uk/co/mycompany/ui/main/di/ViewModelKey.kt b/app/src/main/java/uk/co/mycompany/ui/main/di/ViewModelKey.kt new file mode 100644 index 0000000..ce122aa --- /dev/null +++ b/app/src/main/java/uk/co/mycompany/ui/main/di/ViewModelKey.kt @@ -0,0 +1,18 @@ +package uk.co.mycompany.ui.main.di + +import android.arch.lifecycle.ViewModel +import dagger.MapKey +import java.lang.annotation.* +import java.lang.annotation.Retention +import kotlin.annotation.AnnotationTarget.FUNCTION +import kotlin.reflect.KClass + +/** + * Created by Md. Sifat-Ul Haque on 1/29/2018. + */ + +@Documented +@Target(FUNCTION) +@Retention(RetentionPolicy.RUNTIME) +@MapKey +annotation class ViewModelKey(val value: KClass) \ No newline at end of file diff --git a/app/src/main/java/uk/co/mycompany/ui/main/di/ViewModelModule.kt b/app/src/main/java/uk/co/mycompany/ui/main/di/ViewModelModule.kt new file mode 100644 index 0000000..cdefa82 --- /dev/null +++ b/app/src/main/java/uk/co/mycompany/ui/main/di/ViewModelModule.kt @@ -0,0 +1,25 @@ +package uk.co.mycompany.ui.main.di + +import android.arch.lifecycle.ViewModel +import android.arch.lifecycle.ViewModelProvider +import dagger.Binds +import dagger.Module +import dagger.multibindings.IntoMap +import uk.co.mycompany.ui.main.MainActivityViewModel +import uk.co.mycompany.ui.main.ViewModelFactory +import uk.co.mycompany.ui.main.ViewModelKey + +/** + * Created by Md. Sifat-Ul Haque on 1/29/2018. + */ +@Module +open abstract class ViewModelModule { + + @Binds + @IntoMap + @ViewModelKey(MainActivityViewModel::class) + abstract fun bindsMainViewModel(mainActivityViewModel: MainActivityViewModel): ViewModel + + @Binds + abstract fun bindsViewModelFactory(viewModelFactory: ViewModelFactory): ViewModelProvider.Factory +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 13c818e..95f383b 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,6 +7,7 @@ tools:context="uk.co.mycompany.ui.main.MainActivity">