android 如何使用koin注入View模型?(适用于特定用例)

eqoofvh9  于 2023-10-14  发布在  Android
关注(0)|答案(2)|浏览(143)

我有一个共享的活动视图模型,它的片段。
当从Activity示例化时,我的视图模型需要传递的参数(onCreate仅一次)

viewModel =ViewModelProviders.of(this,
                                 NoteViewModelFactory(application!!,
                                                      uid = intent!!.getStringExtra("uid")!!))
                             .get(NoteViewModel::class.java)

但是在fragment中,我不需要传递参数,因为我确定参数已经传递过一次了。

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:无法启动活动NotesInfo {com. andor. navigate. notepad/com. andor. navigate. notepad. listing. NotesActivity}:org. koin. core. error. InstanceCreationException:无法为[type:工厂,primary_type:'com.等等。导航。记事本。核心Android上的NoteViewModel。app. ActivityThread. performLaunchActivity(ActivityThread.java:2665)at android. app. ActivityThread.在android.app.ActivityThread上搜索LaunchActivity(ActivityThread.java:2726)。-wrap12(www.example.com)在android. app. ActivityThread $H。在android上查看消息(ActivityThread.java:1477)。骨密度android上的dispatchMessage(Handler.java:102)。os. Looper.循环(Looper.java:154)在android. app. ActivityThread. main(ActivityThread.java:6119)在java中。lang。反思。方法。在com上调用(本地方法)。机器人内部的os. ZygoteInit $www.example.com(ZygoteInit.java:886)at com.机器人内部的os. ZygoteInit. main(ZygoteInit.java:776)原因:ActivityThread.java无法创建[type:Factory,primary_type:'com. andor. navigate. notepad. core. NoteViewModel ']的示例,位于org. koin. core. instance. FactoryViewInstance. create(FactoryViewInstance. kt:61),位于org. koin. core. instance. FactoryViewInstance. get(FactoryViewInstance. kt:37),位于org. koin. core. definition. BeanDefinition. resolveInstance(BeanDefinition. kt:70),位于org. koin. core. scope. Scope. resolveInstance(Scope. kt:165)
我不知道如何使用KOIN解决这个问题。
P. S:我是新来的。

vxf3dgd4

vxf3dgd41#

在应用类中初始化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)
yquaqz18

yquaqz182#

你不应该在ViewModel构造函数中传递这些类型的参数。相反,您可以在Activity的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)
}

}

相关问题