ฉันกำลังพยายามเพิ่ม Dagger 2 ในโครงการของฉัน ฉันสามารถฉีด ViewModels (ส่วนประกอบ AndroidX Architecture) สำหรับชิ้นส่วนของฉัน
ฉันมีViewPager ซึ่งมี 2 อินสแตนซ์ของแฟรกเมนต์เดียวกัน (เฉพาะการเปลี่ยนแปลงเล็กน้อยสำหรับแต่ละแท็บ) และในแต่ละแท็บฉันกำลังเฝ้าดูLiveData
เพื่อรับการอัปเดตเกี่ยวกับการเปลี่ยนแปลงข้อมูล (จาก API)
ปัญหาคือเมื่อการตอบสนอง api มาและอัปเดตLiveData
ข้อมูลเดียวกันในส่วนที่มองเห็นได้ในปัจจุบันจะถูกส่งไปยังผู้สังเกตการณ์ในแท็บทั้งหมด (ฉันคิดว่านี่อาจเป็นเพราะขอบเขตของViewModel
)
นี่คือวิธีที่ฉันสังเกตข้อมูลของฉัน:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
activityViewModel.expenseList.observe(this, Observer {
swipeToRefreshLayout.isRefreshing = false
viewAdapter.setData(it)
})
....
}
ฉันใช้คลาสนี้ในการจัดหา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"
}
}
ฉันผูกพันของฉันViewModel
เช่นนี้:
@Module
abstract class ActivityViewModelModule {
@MainScope
@Binds
@IntoMap
@ViewModelKey(ActivityViewModel::class)
abstract fun bindActivityViewModel(viewModel: ActivityViewModel): ViewModel
}
ฉันใช้@ContributesAndroidInjector
ชิ้นส่วนของฉันเช่นนี้:
@Module
abstract class MainFragmentBuildersModule {
@ContributesAndroidInjector
abstract fun contributeActivityFragment(): ActivityFragment
}
และฉันกำลังเพิ่มโมดูลเหล่านี้ไปยังMainActivity
คอมโพเนนต์ย่อยของฉันเช่นนี้:
@Module
abstract class ActivityBuilderModule {
...
@ContributesAndroidInjector(
modules = [MainViewModelModule::class, ActivityViewModelModule::class,
AuthModule::class, MainFragmentBuildersModule::class]
)
abstract fun contributeMainActivity(): MainActivity
}
นี่คือของฉัน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
}
}
ฉันกำลังขยายDaggerFragment
และฉีดViewModelProviderFactory
แบบนี้:
@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)
}
key
จะแตกต่างกันสำหรับทั้งเศษ
ฉันจะมั่นใจได้อย่างไรว่ามีเพียงผู้สังเกตการณ์ของแฟรกเมนต์ปัจจุบันเท่านั้นที่ได้รับการอัปเดต
แก้ไข 1 ->
ฉันได้เพิ่มโครงการตัวอย่างพร้อมข้อผิดพลาด ดูเหมือนว่าปัญหาจะเกิดขึ้นเฉพาะเมื่อมีการเพิ่มขอบเขตที่กำหนดเอง กรุณาตรวจสอบโครงการตัวอย่างที่นี่: ลิงค์ Github
master
สาขามีแอปที่มีปัญหา หากคุณรีเฟรชแท็บใด ๆ (ปัดเพื่อรีเฟรช) ค่าที่อัพเดตจะได้รับการสะท้อนในแท็บทั้งสอง สิ่งนี้จะเกิดขึ้นเมื่อฉันเพิ่มขอบเขตที่กำหนดเองลงในมัน ( @MainScope
)
working_fine
Branch มีแอพเดียวกันที่ไม่มีขอบเขตที่กำหนดเองและใช้ได้ดี
โปรดแจ้งให้เราทราบหากคำถามไม่ชัดเจน
working_fine
สาขา ทำไมคุณถึงต้องการขอบเขต?