我有一个活动的共享视图模型,它是片段。
从活动实例化时,仅需要传递我的视图模型的参数(onCreate
一次)
viewModel =ViewModelProviders.of(this,
NoteViewModelFactory(application!!,
uid = intent!!.getStringExtra("uid")!!))
.get(NoteViewModel::class.java)
但是从片段中我不需要传递参数,因为我确定参数传递了一次。
viewModel = ViewModelProviders.of(activity!!).get(NoteViewModel::class.java)
我在Koin
中尝试了以下操作。
val noteModule = module(override = true) {
viewModel { (id: String) -> NoteViewModel(androidApplication(), id) }
}
活动中:
private val viewModel: NoteViewModel by viewModel { parametersOf(intent!!.getStringExtra("uid")!!) }
在片段中:
private val viewModel: NoteViewModel by sharedViewModel()
应用程序崩溃,出现以下错误:
java.lang.RuntimeException:无法启动活动 ComponentInfo {com.andor.navigate.notepad / com.andor.navigate.notepad.listing.NotesActivity}: org.koin.core.error.InstanceCreationException:无法创建 的实例 [type:Factory,primary_type:'com.andor.navigate.notepad.core.NoteViewModel'] 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665) 在android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 在android.app.ActivityThread.-wrap12(ActivityThread.java) 在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1477) 在android.os.Handler.dispatchMessage(Handler.java:102) 在android.os.Looper.loop(Looper.java:154) 在android.app.ActivityThread.main(ActivityThread.java:6119) 在java.lang.reflect.Method.invoke(本机方法) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:886) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 原因:org.koin.core.error.InstanceCreationException:无法创建实例 [type:Factory,primary_type:'com.andor.navigate.notepad.core.NoteViewModel'] 在org.koin.core.instance.DefinitionInstance.create(DefinitionInstance.kt:61) 在org.koin.core.instance.FactoryDefinitionInstance.get(FactoryDefinitionInstance.kt:37) 在org.koin.core.definition.BeanDefinition.resolveInstance(BeanDefinition.kt:70) 在org.koin.core.scope.Scope.resolveInstance(Scope.kt:165)
我无法理解如何使用KOIN解决此问题。
P.S:我是koin DI的新手。
答案 0 :(得分:0)
在应用程序类中初始化koin时有什么问题吗?我没有任何麻烦地尝试了您的代码。我正在使用koin版本2.0.1
class App : Application() {
override fun onCreate() {
super.onCreate()
val noteModule = module(override = true) {
viewModel { (id: String) -> NoteViewModel(androidApplication(), id) }
}
startKoin {
androidContext(this@App)
modules(
noteModule
)
}
}
}
活动和片段:
class MainActivity : AppCompatActivity() {
private val viewModel: NoteViewModel by viewModel { parametersOf(intent!!.getStringExtra("uid")) }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("NoteViewModel", "id: ${viewModel.id}")
supportFragmentManager.beginTransaction().replace(R.id.main_root, Frag()).commit()
}
}
class Frag : Fragment() {
private val viewModel: NoteViewModel by sharedViewModel()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
Log.d("NoteViewModel", "id: ${viewModel.id}")
return inflater.inflate(R.layout.activity_main, container, false)
}
}
查看模型类:
class NoteViewModel (application: Application, val id: String) : AndroidViewModel(application)
答案 1 :(得分:0)
您不应在ViewModel
构造函数中传递这些类型的参数。相反,您可以做的是在“活动”的onCreate()
上,将传递的值设置为ViewModel
。因此,当您访问片段中的ViewModel
时,肯定会设置该值。
class NoteViewModel (application: Application) : AndroidViewModel(application)
{
var id:String = ""
}
您的koin模块:
val noteModule = module(override = true) {
viewModel { NoteViewModel(androidApplication()) }
}
活动:
class MainActivity : AppCompatActivity() {
private val viewModel: NoteViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel.id = intent?.getStringExtra("uid")?: ""
supportFragmentManager.beginTransaction().replace(R.id.container, MyFrag()).commit()
}
}
片段:
class MyFrag : Fragment() {
private val viewModel: NoteViewModel by sharedViewModel()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// your value will be available here.
return inflater.inflate(R.layout.activity_main, container, false)
}
}