diff --git a/GithubBrowserSample/app/build.gradle b/GithubBrowserSample/app/build.gradle index fd15b3b6..6f061f0f 100644 --- a/GithubBrowserSample/app/build.gradle +++ b/GithubBrowserSample/app/build.gradle @@ -17,7 +17,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' - +apply plugin: 'dagger.hilt.android.plugin' apply plugin: 'kotlin-allopen' apply plugin: 'androidx.navigation.safeargs.kotlin' @@ -81,16 +81,13 @@ dependencies { implementation deps.retrofit.gson implementation deps.glide.runtime - implementation deps.dagger.runtime - implementation deps.dagger.android - implementation deps.dagger.android_support + implementation deps.dagger.hilt_android implementation deps.constraint_layout implementation deps.kotlin.stdlib implementation deps.timber - kapt deps.dagger.android_support_compiler - kapt deps.dagger.compiler + kapt deps.dagger.hilt_compiler kapt deps.room.compiler kapt deps.lifecycle.compiler diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/GithubApp.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/GithubApp.kt index 71b9c747..f199729f 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/GithubApp.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/GithubApp.kt @@ -16,26 +16,18 @@ package com.android.example.github -import android.app.Activity import android.app.Application -import com.android.example.github.di.AppInjector -import dagger.android.DispatchingAndroidInjector -import dagger.android.HasActivityInjector +import dagger.hilt.android.HiltAndroidApp import timber.log.Timber -import javax.inject.Inject - -class GithubApp : Application(), HasActivityInjector { - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector +@HiltAndroidApp +class GithubApp : Application() { override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) { Timber.plant(Timber.DebugTree()) } - AppInjector.init(this) } - override fun activityInjector() = dispatchingAndroidInjector } diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/MainActivity.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/MainActivity.kt index 03cc87b9..6821055a 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/MainActivity.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/MainActivity.kt @@ -17,20 +17,15 @@ package com.android.example.github import android.os.Bundle -import androidx.fragment.app.Fragment import androidx.appcompat.app.AppCompatActivity -import dagger.android.DispatchingAndroidInjector -import dagger.android.support.HasSupportFragmentInjector -import javax.inject.Inject +import dagger.hilt.android.AndroidEntryPoint -class MainActivity : AppCompatActivity(), HasSupportFragmentInjector { - @Inject - lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector +@AndroidEntryPoint +class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main_activity) } - override fun supportFragmentInjector() = dispatchingAndroidInjector } diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppComponent.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppComponent.kt deleted file mode 100644 index a696df41..00000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppComponent.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.example.github.di - -import android.app.Application -import com.android.example.github.GithubApp -import dagger.BindsInstance -import dagger.Component -import dagger.android.AndroidInjectionModule -import javax.inject.Singleton - -@Singleton -@Component( - modules = [ - AndroidInjectionModule::class, - AppModule::class, - MainActivityModule::class] -) -interface AppComponent { - @Component.Builder - interface Builder { - @BindsInstance - fun application(application: Application): Builder - - fun build(): AppComponent - } - - fun inject(githubApp: GithubApp) -} diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppInjector.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppInjector.kt deleted file mode 100644 index 67b4d346..00000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppInjector.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.example.github.di - -import android.app.Activity -import android.app.Application -import android.os.Bundle -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity -import androidx.fragment.app.FragmentManager -import com.android.example.github.GithubApp -import dagger.android.AndroidInjection -import dagger.android.support.AndroidSupportInjection -import dagger.android.support.HasSupportFragmentInjector - -/** - * Helper class to automatically inject fragments if they implement [Injectable]. - */ -object AppInjector { - fun init(githubApp: GithubApp) { - DaggerAppComponent.builder().application(githubApp) - .build().inject(githubApp) - githubApp - .registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks { - override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { - handleActivity(activity) - } - - override fun onActivityStarted(activity: Activity) { - - } - - override fun onActivityResumed(activity: Activity) { - - } - - override fun onActivityPaused(activity: Activity) { - - } - - override fun onActivityStopped(activity: Activity) { - - } - - override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) { - - } - - override fun onActivityDestroyed(activity: Activity) { - - } - }) - } - - private fun handleActivity(activity: Activity) { - if (activity is HasSupportFragmentInjector) { - AndroidInjection.inject(activity) - } - if (activity is FragmentActivity) { - activity.supportFragmentManager - .registerFragmentLifecycleCallbacks( - object : FragmentManager.FragmentLifecycleCallbacks() { - override fun onFragmentCreated( - fm: FragmentManager, - f: Fragment, - savedInstanceState: Bundle? - ) { - if (f is Injectable) { - AndroidSupportInjection.inject(f) - } - } - }, true - ) - } - } -} diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppModule.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppModule.kt index ade8ae81..4b139227 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppModule.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppModule.kt @@ -25,11 +25,14 @@ import com.android.example.github.db.UserDao import com.android.example.github.util.LiveDataCallAdapterFactory import dagger.Module import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import javax.inject.Singleton -@Module(includes = [ViewModelModule::class]) +@Module +@InstallIn(SingletonComponent::class) class AppModule { @Singleton @Provides diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/FragmentBuildersModule.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/FragmentBuildersModule.kt deleted file mode 100644 index 3c61ff7c..00000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/FragmentBuildersModule.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.example.github.di - -import com.android.example.github.ui.repo.RepoFragment -import com.android.example.github.ui.search.SearchFragment -import com.android.example.github.ui.user.UserFragment - -import dagger.Module -import dagger.android.ContributesAndroidInjector - -@Suppress("unused") -@Module -abstract class FragmentBuildersModule { - @ContributesAndroidInjector - abstract fun contributeRepoFragment(): RepoFragment - - @ContributesAndroidInjector - abstract fun contributeUserFragment(): UserFragment - - @ContributesAndroidInjector - abstract fun contributeSearchFragment(): SearchFragment -} diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/Injectable.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/Injectable.kt deleted file mode 100644 index e393b9d5..00000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/Injectable.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.example.github.di - -/** - * Marks an activity / fragment injectable. - */ -interface Injectable diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/MainActivityModule.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/MainActivityModule.kt deleted file mode 100644 index 1b6d9cd3..00000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/MainActivityModule.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.example.github.di - -import com.android.example.github.MainActivity - -import dagger.Module -import dagger.android.ContributesAndroidInjector - -@Suppress("unused") -@Module -abstract class MainActivityModule { - @ContributesAndroidInjector(modules = [FragmentBuildersModule::class]) - abstract fun contributeMainActivity(): MainActivity -} diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelModule.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelModule.kt deleted file mode 100644 index 44f42699..00000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelModule.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.example.github.di - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider - -import com.android.example.github.ui.repo.RepoViewModel -import com.android.example.github.ui.search.SearchViewModel -import com.android.example.github.ui.user.UserViewModel -import com.android.example.github.viewmodel.GithubViewModelFactory - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoMap - -@Suppress("unused") -@Module -abstract class ViewModelModule { - @Binds - @IntoMap - @ViewModelKey(UserViewModel::class) - abstract fun bindUserViewModel(userViewModel: UserViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(SearchViewModel::class) - abstract fun bindSearchViewModel(searchViewModel: SearchViewModel): ViewModel - - @Binds - @IntoMap - @ViewModelKey(RepoViewModel::class) - abstract fun bindRepoViewModel(repoViewModel: RepoViewModel): ViewModel - - @Binds - abstract fun bindViewModelFactory(factory: GithubViewModelFactory): ViewModelProvider.Factory -} diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoFragment.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoFragment.kt index 59c43b0c..c8dc7a02 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoFragment.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoFragment.kt @@ -26,7 +26,6 @@ import androidx.databinding.DataBindingUtil import androidx.fragment.app.Fragment import androidx.fragment.app.viewModels import androidx.lifecycle.Observer -import androidx.lifecycle.ViewModelProvider import androidx.navigation.fragment.FragmentNavigatorExtras import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs @@ -35,22 +34,18 @@ import com.android.example.github.AppExecutors import com.android.example.github.R import com.android.example.github.binding.FragmentDataBindingComponent import com.android.example.github.databinding.RepoFragmentBinding -import com.android.example.github.di.Injectable import com.android.example.github.ui.common.RetryCallback import com.android.example.github.util.autoCleared +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject /** * The UI Controller for displaying a Github Repo's information with its contributors. */ -class RepoFragment : Fragment(), Injectable { +@AndroidEntryPoint +class RepoFragment : Fragment() { - @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory - - val repoViewModel: RepoViewModel by viewModels { - viewModelFactory - } + val repoViewModel: RepoViewModel by viewModels() @Inject lateinit var appExecutors: AppExecutors diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoViewModel.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoViewModel.kt index 52fa9da3..394e57f0 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoViewModel.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/repo/RepoViewModel.kt @@ -26,8 +26,10 @@ import com.android.example.github.util.AbsentLiveData import com.android.example.github.vo.Contributor import com.android.example.github.vo.Repo import com.android.example.github.vo.Resource +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +@HiltViewModel @OpenForTesting class RepoViewModel @Inject constructor(repository: RepoRepository) : ViewModel() { private val _repoId: MutableLiveData = MutableLiveData() diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchFragment.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchFragment.kt index 1a6bbe43..0181b157 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchFragment.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchFragment.kt @@ -38,17 +38,15 @@ import com.android.example.github.AppExecutors import com.android.example.github.R import com.android.example.github.binding.FragmentDataBindingComponent import com.android.example.github.databinding.SearchFragmentBinding -import com.android.example.github.di.Injectable import com.android.example.github.ui.common.RepoListAdapter import com.android.example.github.ui.common.RetryCallback import com.android.example.github.util.autoCleared import com.google.android.material.snackbar.Snackbar +import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject -class SearchFragment : Fragment(), Injectable { - - @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory +@AndroidEntryPoint +class SearchFragment : Fragment() { @Inject lateinit var appExecutors: AppExecutors @@ -59,9 +57,7 @@ class SearchFragment : Fragment(), Injectable { var adapter by autoCleared() - val searchViewModel: SearchViewModel by viewModels { - viewModelFactory - } + val searchViewModel: SearchViewModel by viewModels() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchViewModel.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchViewModel.kt index 846a3bf4..217479e4 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchViewModel.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/search/SearchViewModel.kt @@ -27,9 +27,11 @@ import com.android.example.github.util.AbsentLiveData import com.android.example.github.vo.Repo import com.android.example.github.vo.Resource import com.android.example.github.vo.Status +import dagger.hilt.android.lifecycle.HiltViewModel import java.util.Locale import javax.inject.Inject +@HiltViewModel @OpenForTesting class SearchViewModel @Inject constructor(repoRepository: RepoRepository) : ViewModel() { diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserFragment.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserFragment.kt index 6cff9c35..f2a78084 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserFragment.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserFragment.kt @@ -34,7 +34,6 @@ import com.android.example.github.AppExecutors import com.android.example.github.R import com.android.example.github.binding.FragmentDataBindingComponent import com.android.example.github.databinding.UserFragmentBinding -import com.android.example.github.di.Injectable import com.android.example.github.ui.common.RepoListAdapter import com.android.example.github.ui.common.RetryCallback import com.android.example.github.util.autoCleared @@ -42,21 +41,20 @@ import com.bumptech.glide.load.DataSource import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.request.RequestListener import com.bumptech.glide.request.target.Target +import dagger.hilt.android.AndroidEntryPoint import java.util.concurrent.TimeUnit import javax.inject.Inject -class UserFragment : Fragment(), Injectable { - @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory +@AndroidEntryPoint +class UserFragment : Fragment() { + @Inject lateinit var appExecutors: AppExecutors var binding by autoCleared() var dataBindingComponent: DataBindingComponent = FragmentDataBindingComponent(this) - private val userViewModel: UserViewModel by viewModels { - viewModelFactory - } + private val userViewModel: UserViewModel by viewModels() private val params by navArgs() private var adapter by autoCleared() diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserViewModel.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserViewModel.kt index 80ca7d66..3ffeb370 100644 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserViewModel.kt +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/ui/user/UserViewModel.kt @@ -27,8 +27,10 @@ import com.android.example.github.util.AbsentLiveData import com.android.example.github.vo.Repo import com.android.example.github.vo.Resource import com.android.example.github.vo.User +import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +@HiltViewModel @OpenForTesting class UserViewModel @Inject constructor(userRepository: UserRepository, repoRepository: RepoRepository) : ViewModel() { diff --git a/GithubBrowserSample/build.gradle b/GithubBrowserSample/build.gradle index e7cbea4d..c1356fae 100644 --- a/GithubBrowserSample/build.gradle +++ b/GithubBrowserSample/build.gradle @@ -23,6 +23,7 @@ buildscript { classpath deps.kotlin.plugin classpath deps.kotlin.allopen classpath deps.navigation.safe_args_plugin + classpath deps.dagger.hilt_plugin // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } diff --git a/GithubBrowserSample/versions.gradle b/GithubBrowserSample/versions.gradle index 72045795..a1718d70 100644 --- a/GithubBrowserSample/versions.gradle +++ b/GithubBrowserSample/versions.gradle @@ -36,14 +36,14 @@ versions.cardview = "1.0.0" versions.constraint_layout = "2.0.0-alpha2" versions.core_ktx = "1.1.0" versions.coroutines = "1.6.0" -versions.dagger = "2.16" +versions.dagger = "2.41" versions.dexmaker = "2.2.0" versions.espresso = "3.2.0" versions.fragment = "1.2.0" versions.glide = "4.8.0" versions.hamcrest = "1.3" versions.junit = "4.12" -versions.kotlin = "1.6.10" +versions.kotlin = "1.6.20" versions.lifecycle = "2.2.0" versions.material = "1.0.0" versions.mockito = "2.25.0" @@ -112,11 +112,9 @@ coroutines.test = "org.jetbrains.kotlinx:kotlinx-coroutines-test:$versions.corou deps.coroutines = coroutines def dagger = [:] -dagger.runtime = "com.google.dagger:dagger:$versions.dagger" -dagger.android = "com.google.dagger:dagger-android:$versions.dagger" -dagger.android_support = "com.google.dagger:dagger-android-support:$versions.dagger" -dagger.compiler = "com.google.dagger:dagger-compiler:$versions.dagger" -dagger.android_support_compiler = "com.google.dagger:dagger-android-processor:$versions.dagger" +dagger.hilt_plugin = "com.google.dagger:hilt-android-gradle-plugin:$versions.dagger" +dagger.hilt_android = "com.google.dagger:hilt-android:$versions.dagger" +dagger.hilt_compiler = "com.google.dagger:hilt-compiler:$versions.dagger" deps.dagger = dagger deps.dexmaker = "com.linkedin.dexmaker:dexmaker-mockito:$versions.dexmaker"