2017-06-19 11 views
17

मैं एक मानचित्र में अपने KClass प्रकार से ViewModel की उपवर्गों बाध्य करने के लिए कोशिश कर रहा हूँ के साथ नक्शे में बाइंडिंग:KClass प्रकार

@Module abstract class ViewModelModule { 

    @Binds @IntoMap @ViewModelKey(MyViewModel::class) 
    abstract fun bindsMyViewModel(viewModel: MyViewModel): ViewModel 

    @Binds abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory 

} 

लेकिन मैं डैगर संकलक त्रुटि हो रही है:

e: ~/Example/app/build/tmp/kapt3/stubs/debug/com/example/app/injection/AppComponent.java:5: error: [dagger.android.AndroidInjector.inject(T)] java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> cannot be provided without an @Provides-annotated method. 
e: 

e: public abstract interface AppComponent { 
e:    ^
e:  java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> is injected at 
e:   com.example.app.ui.ViewModelFactory.<init>(creators) 
e:  com.example.app.ui.ViewModelFactory is injected at 
e:   com.example.app.injection.ViewModelModule.bindViewModelFactory(p0) 
e:  android.arch.lifecycle.ViewModelProvider.Factory is injected at 
e:   com.example.app.ui.MyFragment.setViewModelFactory(p0) 
e:  com.example.app.ui.MyFragment is injected at 
e:   dagger.android.AndroidInjector.inject(arg0) 

ऊपर ViewModelModule मेरे AppModule में शामिल है, जो मेरे AppComponent में एक मॉड्यूल है। तो डैगर Map<KClass<out ViewModel>, Provider<ViewModel>> को मेरे ViewModelFactory द्वारा आवश्यक प्रदान करने में सक्षम होना चाहिए, लेकिन मुझे पता नहीं चल रहा है कि यह क्यों क्रैश हो रहा है।


मैं भी जावा के लिए खत्म हो ViewModelKey एनोटेशन वर्ग स्विचन की कोशिश की, एक Class एक KClass के बजाय एक निर्माता पैरामीटर के रूप में ले रही है। फिर ViewModelFactory को Map<Class<out ViewModel>, Provider<ViewModel>> पर निर्भर करने के लिए संशोधित किया गया, लेकिन एक ही त्रुटि हुई।

उत्तर

30

एनोटेशन में KClass का उपयोग करते समय, यह वास्तव में जावा के Class पर संकलित हो जाता है। लेकिन असली मुद्दा java.util.Map<kotlin.reflect.KClass<? extends android.arch.lifecycle.ViewModel>,? extends javax.inject.Provider<android.arch.lifecycle.ViewModel>> में वाइल्डकार्ड है जो कोटलिन कंपाइलर उत्पन्न कर रहा है।

कि @ViewModelKey मान लिया जाये कि के रूप में

@MapKey 
annotation class ViewModelKey(val value: KClass<out ViewModel>) 

आप

Map<Class<out ViewModel>, @JvmSuppressWildcards Provider<ViewModel>> 

@JvmSuppressWildcards का उपयोग करते हुए पैदा करने के लिए वाइल्डकार्ड से संकलक पाएगा रूप में अपने इंजेक्शन स्थल निर्धारित करने होंगे परिभाषित किया गया है।

मुझे वास्तव में पता नहीं है, क्यों डैगर कंपाइलर द्वारा वाइल्डकार्ड समर्थित नहीं हैं। आप यहां एक समान समस्या देख सकते हैं: Dagger 2: How to inject Map<Class<? extends Foo>, Provider<? extends Foo>>

+1

आप शानदार हैं, बहुत धन्यवाद – Roman

+0

कमाल। मैं इसे कभी नहीं मिला होता, सभी Google एंड्रॉइड आर्किटेक्चर परियोजनाएं जावा में हैं! – Arjun

संबंधित मुद्दे