diff --git a/GithubBrowserSample/app/build.gradle b/GithubBrowserSample/app/build.gradle index fd15b3b60..e24aeef02 100644 --- a/GithubBrowserSample/app/build.gradle +++ b/GithubBrowserSample/app/build.gradle @@ -20,6 +20,7 @@ apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-allopen' apply plugin: 'androidx.navigation.safeargs.kotlin' +apply plugin: 'dagger.hilt.android.plugin' allOpen { // allows mocking for classes w/o directly opening them for release builds @@ -87,6 +88,11 @@ dependencies { implementation deps.constraint_layout implementation deps.kotlin.stdlib + implementation deps.hilt.runtime + implementation deps.hilt.lifecycle_viewmodel + kapt deps.hilt.compiler + kapt deps.hilt.androidx_compiler + implementation deps.timber kapt deps.dagger.android_support_compiler diff --git a/GithubBrowserSample/app/src/debug/java/com/android/example/github/testing/SingleFragmentActivity.kt b/GithubBrowserSample/app/src/debug/java/com/android/example/github/testing/SingleFragmentActivity.kt index 6d4cf7682..ba3735a5b 100644 --- a/GithubBrowserSample/app/src/debug/java/com/android/example/github/testing/SingleFragmentActivity.kt +++ b/GithubBrowserSample/app/src/debug/java/com/android/example/github/testing/SingleFragmentActivity.kt @@ -23,17 +23,20 @@ import android.view.ViewGroup import android.widget.FrameLayout import androidx.fragment.app.FragmentContainerView import com.android.example.github.R +import dagger.hilt.android.AndroidEntryPoint /** * Used for testing fragments inside a fake activity. */ + +@AndroidEntryPoint class SingleFragmentActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val content = FragmentContainerView(this).apply { layoutParams = FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT ) id = R.id.container } @@ -42,18 +45,18 @@ class SingleFragmentActivity : AppCompatActivity() { fun setFragment(fragment: Fragment) { supportFragmentManager.beginTransaction() - .add(R.id.container, fragment, "TEST") - .commit() + .add(R.id.container, fragment, "TEST") + .commit() } fun replaceFragment(fragment: Fragment, addToBackStack: Boolean = false) { supportFragmentManager.beginTransaction() - .replace(R.id.container, fragment) - .apply { - if (addToBackStack) { - addToBackStack(null) + .replace(R.id.container, fragment) + .apply { + if (addToBackStack) { + addToBackStack(null) + } } - } - .commit() + .commit() } } 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 71b9c747e..ceb63bf0b 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,17 @@ 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 03cc87b93..9fe6c5fcf 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,14 @@ 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 a696df41f..000000000 --- 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 67b4d346b..000000000 --- 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 deleted file mode 100644 index ade8ae818..000000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/AppModule.kt +++ /dev/null @@ -1,65 +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 androidx.room.Room -import com.android.example.github.api.GithubService -import com.android.example.github.db.GithubDb -import com.android.example.github.db.RepoDao -import com.android.example.github.db.UserDao -import com.android.example.github.util.LiveDataCallAdapterFactory -import dagger.Module -import dagger.Provides -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory -import javax.inject.Singleton - -@Module(includes = [ViewModelModule::class]) -class AppModule { - @Singleton - @Provides - fun provideGithubService(): GithubService { - return Retrofit.Builder() - .baseUrl("https://api.github.com/") - .addConverterFactory(GsonConverterFactory.create()) - .addCallAdapterFactory(LiveDataCallAdapterFactory()) - .build() - .create(GithubService::class.java) - } - - @Singleton - @Provides - fun provideDb(app: Application): GithubDb { - return Room - .databaseBuilder(app, GithubDb::class.java, "github.db") - .fallbackToDestructiveMigration() - .build() - } - - @Singleton - @Provides - fun provideUserDao(db: GithubDb): UserDao { - return db.userDao() - } - - @Singleton - @Provides - fun provideRepoDao(db: GithubDb): RepoDao { - return db.repoDao() - } -} 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 3c61ff7c9..000000000 --- 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 e393b9d5d..000000000 --- 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 1b6d9cd3e..000000000 --- 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/NetworkModule.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/NetworkModule.kt new file mode 100644 index 000000000..c32862920 --- /dev/null +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/NetworkModule.kt @@ -0,0 +1,27 @@ +package com.android.example.github.di + +import com.android.example.github.api.GithubService +import com.android.example.github.util.LiveDataCallAdapterFactory +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ApplicationComponent +import retrofit2.Retrofit +import retrofit2.converter.gson.GsonConverterFactory +import javax.inject.Singleton + +@Module +@InstallIn(ApplicationComponent::class) +object NetworkModule { + + @Singleton + @Provides + fun provideGithubService(): GithubService { + return Retrofit.Builder() + .baseUrl("https://api.github.com/") + .addConverterFactory(GsonConverterFactory.create()) + .addCallAdapterFactory(LiveDataCallAdapterFactory()) + .build() + .create(GithubService::class.java) + } +} \ No newline at end of file diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/PersistenceModule.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/PersistenceModule.kt new file mode 100644 index 000000000..fa6f8b3fb --- /dev/null +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/PersistenceModule.kt @@ -0,0 +1,38 @@ +package com.android.example.github.di + +import android.app.Application +import androidx.room.Room +import com.android.example.github.db.GithubDb +import com.android.example.github.db.RepoDao +import com.android.example.github.db.UserDao +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ApplicationComponent +import javax.inject.Singleton + +@Module +@InstallIn(ApplicationComponent::class) +object PersistenceModule { + + @Singleton + @Provides + fun provideDb(app: Application): GithubDb { + return Room + .databaseBuilder(app, GithubDb::class.java, "github.db") + .fallbackToDestructiveMigration() + .build() + } + + @Singleton + @Provides + fun provideUserDao(db: GithubDb): UserDao { + return db.userDao() + } + + @Singleton + @Provides + fun provideRepoDao(db: GithubDb): RepoDao { + return db.repoDao() + } +} \ No newline at end of file diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/RepositoryModule.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/RepositoryModule.kt new file mode 100644 index 000000000..ccda4c359 --- /dev/null +++ b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/RepositoryModule.kt @@ -0,0 +1,11 @@ +package com.android.example.github.di + +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ApplicationComponent + +@Module +@InstallIn(ApplicationComponent::class) +object RepositoryModule { + +} \ No newline at end of file diff --git a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelKey.kt b/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelKey.kt deleted file mode 100644 index 02f948704..000000000 --- a/GithubBrowserSample/app/src/main/java/com/android/example/github/di/ViewModelKey.kt +++ /dev/null @@ -1,31 +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 dagger.MapKey -import kotlin.reflect.KClass - -@MustBeDocumented -@Target( - AnnotationTarget.FUNCTION, - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.PROPERTY_SETTER -) -@Retention(AnnotationRetention.RUNTIME) -@MapKey -annotation class ViewModelKey(val value: KClass) 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 44f42699a..000000000 --- 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 59c43b0c6..2fc613ae5 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,19 @@ 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 { - @Inject - lateinit var viewModelFactory: ViewModelProvider.Factory +@AndroidEntryPoint +class RepoFragment : Fragment() { - val repoViewModel: RepoViewModel by viewModels { - viewModelFactory - } + private val repoViewModel: RepoViewModel by viewModels() @Inject lateinit var appExecutors: AppExecutors @@ -75,14 +71,14 @@ class RepoFragment : Fragment(), Injectable { } override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? ): View? { val dataBinding = DataBindingUtil.inflate( - inflater, - R.layout.repo_fragment, - container, - false + inflater, + R.layout.repo_fragment, + container, + false ) dataBinding.retryCallback = object : RetryCallback { override fun retry() { 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 52fa9da38..bdb7fba73 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 @@ -16,6 +16,7 @@ package com.android.example.github.ui.repo +import androidx.hilt.lifecycle.ViewModelInject import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -26,10 +27,9 @@ 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 javax.inject.Inject @OpenForTesting -class RepoViewModel @Inject constructor(repository: RepoRepository) : ViewModel() { +class RepoViewModel @ViewModelInject constructor(repository: RepoRepository) : ViewModel() { private val _repoId: MutableLiveData = MutableLiveData() val repoId: LiveData get() = _repoId 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 1a6bbe43f..bd686168d 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 @@ -30,7 +30,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.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -38,17 +37,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,20 +56,18 @@ class SearchFragment : Fragment(), Injectable { var adapter by autoCleared() - val searchViewModel: SearchViewModel by viewModels { - viewModelFactory - } + private val searchViewModel: SearchViewModel by viewModels() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? ): View? { binding = DataBindingUtil.inflate( - inflater, - R.layout.search_fragment, - container, - false, - dataBindingComponent + inflater, + R.layout.search_fragment, + container, + false, + dataBindingComponent ) return binding.root @@ -82,9 +77,9 @@ class SearchFragment : Fragment(), Injectable { binding.lifecycleOwner = viewLifecycleOwner initRecyclerView() val rvAdapter = RepoListAdapter( - dataBindingComponent = dataBindingComponent, - appExecutors = appExecutors, - showFullName = true + dataBindingComponent = dataBindingComponent, + appExecutors = appExecutors, + showFullName = true ) { repo -> findNavController().navigate( SearchFragmentDirections.showRepo(repo.owner.login, repo.name) 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 846a3bf47..31509ce71 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 @@ -16,6 +16,7 @@ package com.android.example.github.ui.search +import androidx.hilt.lifecycle.ViewModelInject import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer @@ -28,10 +29,9 @@ import com.android.example.github.vo.Repo import com.android.example.github.vo.Resource import com.android.example.github.vo.Status import java.util.Locale -import javax.inject.Inject @OpenForTesting -class SearchViewModel @Inject constructor(repoRepository: RepoRepository) : ViewModel() { +class SearchViewModel @ViewModelInject constructor(repoRepository: RepoRepository) : ViewModel() { private val _query = MutableLiveData() private val nextPageHandler = NextPageHandler(repoRepository) @@ -105,8 +105,8 @@ class SearchViewModel @Inject constructor(repoRepository: RepoRepository) : View this.query = query nextPageLiveData = repository.searchNextPage(query) loadMoreState.value = LoadMoreState( - isRunning = true, - errorMessage = null + isRunning = true, + errorMessage = null ) nextPageLiveData?.observeForever(this) } @@ -120,20 +120,20 @@ class SearchViewModel @Inject constructor(repoRepository: RepoRepository) : View _hasMore = result.data == true unregister() loadMoreState.setValue( - LoadMoreState( - isRunning = false, - errorMessage = null - ) + LoadMoreState( + isRunning = false, + errorMessage = null + ) ) } Status.ERROR -> { _hasMore = true unregister() loadMoreState.setValue( - LoadMoreState( - isRunning = false, - errorMessage = result.message - ) + LoadMoreState( + isRunning = false, + errorMessage = result.message + ) ) } Status.LOADING -> { @@ -155,8 +155,8 @@ class SearchViewModel @Inject constructor(repoRepository: RepoRepository) : View unregister() _hasMore = true loadMoreState.value = LoadMoreState( - isRunning = false, - errorMessage = null + isRunning = false, + errorMessage = null ) } } 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 6cff9c352..e5b9cfd3d 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 @@ -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.findNavController import androidx.navigation.fragment.navArgs import androidx.transition.TransitionInflater @@ -34,7 +33,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,34 +40,34 @@ 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() override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? ): View? { val dataBinding = DataBindingUtil.inflate( - inflater, - R.layout.user_fragment, - container, - false, - dataBindingComponent + inflater, + R.layout.user_fragment, + container, + false, + dataBindingComponent ) dataBinding.retryCallback = object : RetryCallback { override fun retry() { @@ -102,9 +100,9 @@ class UserFragment : Fragment(), Injectable { binding.user = userViewModel.user binding.lifecycleOwner = viewLifecycleOwner val rvAdapter = RepoListAdapter( - dataBindingComponent = dataBindingComponent, - appExecutors = appExecutors, - showFullName = false + dataBindingComponent = dataBindingComponent, + appExecutors = appExecutors, + showFullName = false ) { repo -> findNavController().navigate(UserFragmentDirections.showRepo(repo.owner.login, repo.name)) } 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 80ca7d664..15b9663c8 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 @@ -16,6 +16,7 @@ package com.android.example.github.ui.user +import androidx.hilt.lifecycle.ViewModelInject import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel @@ -27,11 +28,9 @@ 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 javax.inject.Inject @OpenForTesting -class UserViewModel -@Inject constructor(userRepository: UserRepository, repoRepository: RepoRepository) : ViewModel() { +class UserViewModel @ViewModelInject constructor(userRepository: UserRepository, repoRepository: RepoRepository) : ViewModel() { private val _login = MutableLiveData() val login: LiveData get() = _login diff --git a/GithubBrowserSample/build.gradle b/GithubBrowserSample/build.gradle index e7cbea4d5..79b0a6568 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.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 43897aa89..fade55362 100644 --- a/GithubBrowserSample/versions.gradle +++ b/GithubBrowserSample/versions.gradle @@ -22,7 +22,7 @@ ext.deps = [:] def versions = [:] versions.activity = '1.1.0' -versions.android_gradle_plugin = '4.0.0' +versions.android_gradle_plugin = '4.1.1' versions.annotations = "1.0.0" versions.apache_commons = "2.5" versions.appcompat = "1.2.0-alpha02" @@ -62,6 +62,8 @@ versions.rxjava2 = "2.1.3" versions.timber = "4.7.1" versions.transition = "1.3.0" versions.truth = "1.0.1" +versions.hilt = "2.28-alpha" +versions.androidx_hilt = "1.0.0-alpha02" versions.work = "2.6.0" ext.versions = versions @@ -218,6 +220,14 @@ work.firebase = "androidx.work:work-firebase:$versions.work" work.runtime_ktx = "androidx.work:work-runtime-ktx:$versions.work" deps.work = work +def hilt = [:] +hilt.runtime = "com.google.dagger:hilt-android:$versions.hilt" +hilt.plugin = "com.google.dagger:hilt-android-gradle-plugin:$versions.hilt" +hilt.compiler = "com.google.dagger:hilt-android-compiler:$versions.hilt" +hilt.lifecycle_viewmodel = "androidx.hilt:hilt-lifecycle-viewmodel:$versions.androidx_hilt" +hilt.androidx_compiler = "androidx.hilt:hilt-compiler:$versions.androidx_hilt" +deps.hilt = hilt + ext.deps = deps def addRepos(RepositoryHandler handler) {