Tôi đang cố gắng thêm Dagger 2 vào dự án của mình. Tôi đã có thể tiêm ViewModels (thành phần Kiến trúc AndroidX) cho các mảnh vỡ của mình.
Tôi có một ViewPager có 2 phiên bản của cùng một đoạn (Chỉ một thay đổi nhỏ cho mỗi tab) và trong mỗi tab, tôi đang quan sát một LiveData
để được cập nhật về thay đổi dữ liệu (từ API).
Vấn đề là khi phản hồi api đến và cập nhật LiveData
, cùng một dữ liệu trong đoạn hiện có thể nhìn thấy được gửi đến người quan sát trong tất cả các tab. (Tôi nghĩ rằng điều này có lẽ là do phạm vi của ViewModel
).
Đây là cách tôi đang quan sát dữ liệu của mình:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
activityViewModel.expenseList.observe(this, Observer {
swipeToRefreshLayout.isRefreshing = false
viewAdapter.setData(it)
})
....
}
Tôi đang sử dụng lớp này để cung cấp ViewModel
s:
class ViewModelProviderFactory @Inject constructor(creators: MutableMap<Class<out ViewModel?>?, Provider<ViewModel?>?>?) :
ViewModelProvider.Factory {
private val creators: MutableMap<Class<out ViewModel?>?, Provider<ViewModel?>?>? = creators
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
var creator: Provider<out ViewModel?>? = creators!![modelClass]
if (creator == null) { // if the viewmodel has not been created
// loop through the allowable keys (aka allowed classes with the @ViewModelKey)
for (entry in creators.entries) { // if it's allowed, set the Provider<ViewModel>
if (modelClass.isAssignableFrom(entry.key!!)) {
creator = entry.value
break
}
}
}
// if this is not one of the allowed keys, throw exception
requireNotNull(creator) { "unknown model class $modelClass" }
// return the Provider
return try {
creator.get() as T
} catch (e: Exception) {
throw RuntimeException(e)
}
}
companion object {
private val TAG: String? = "ViewModelProviderFactor"
}
}
Tôi ràng buộc ViewModel
như thế này:
@Module
abstract class ActivityViewModelModule {
@MainScope
@Binds
@IntoMap
@ViewModelKey(ActivityViewModel::class)
abstract fun bindActivityViewModel(viewModel: ActivityViewModel): ViewModel
}
Tôi đang sử dụng @ContributesAndroidInjector
cho đoạn của tôi như thế này:
@Module
abstract class MainFragmentBuildersModule {
@ContributesAndroidInjector
abstract fun contributeActivityFragment(): ActivityFragment
}
Và tôi đang thêm các mô-đun này vào thành MainActivity
phần con của mình như thế này:
@Module
abstract class ActivityBuilderModule {
...
@ContributesAndroidInjector(
modules = [MainViewModelModule::class, ActivityViewModelModule::class,
AuthModule::class, MainFragmentBuildersModule::class]
)
abstract fun contributeMainActivity(): MainActivity
}
Đây là AppComponent
:
@Singleton
@Component(
modules =
[AndroidSupportInjectionModule::class,
ActivityBuilderModule::class,
ViewModelFactoryModule::class,
AppModule::class]
)
interface AppComponent : AndroidInjector<SpenmoApplication> {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
}
Tôi đang gia hạn DaggerFragment
và tiêm ViewModelProviderFactory
như thế này:
@Inject
lateinit var viewModelFactory: ViewModelProviderFactory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
....
activityViewModel =
ViewModelProviders.of(this, viewModelFactory).get(key, ActivityViewModel::class.java)
activityViewModel.restartFetch(hasReceipt)
}
những key
sẽ khác nhau cho cả các mảnh vỡ.
Làm thế nào tôi có thể chắc chắn rằng chỉ người quan sát của đoạn hiện tại mới được cập nhật.
CHỈNH SỬA 1 ->
Tôi đã thêm một dự án mẫu với lỗi. Có vẻ như vấn đề chỉ xảy ra khi một phạm vi tùy chỉnh được thêm vào. Vui lòng kiểm tra dự án mẫu tại đây: Github link
master
chi nhánh có ứng dụng với vấn đề. Nếu bạn làm mới bất kỳ tab nào (vuốt để làm mới), giá trị cập nhật sẽ được phản ánh trong cả hai tab. Điều này chỉ xảy ra khi tôi thêm một phạm vi tùy chỉnh cho nó ( @MainScope
).
working_fine
chi nhánh có cùng một ứng dụng không có phạm vi tùy chỉnh và nó hoạt động tốt.
Xin vui lòng cho tôi biết nếu câu hỏi không rõ ràng.
working_fine
chi nhánh? Tại sao bạn cần phạm vi?