我正在Kotlin中使用Koin
库进行DI
Koin提供by viewmodel()
用于获取ViewModel by sharedViewModel()
的实例,以获取片段中的相同实例。
如何在活动中获取相同的ViewModel实例?我没有找到任何方法来实现这一目标。
答案 0 :(得分:3)
您必须在模块声明中使用viewModel{}
而不是single { SharedViewModel() }
。
private val viewModel: SharedViewModel by viewModel()
而且,您可以在视图中使用viewModel()。
View1
private val viewModel: SharedViewModel by viewModel()
View2
loadKoinModules(module1)
但是您必须在视图开始时加载模块
unloadKoinModules(mainModule)
重要的一点是,必须在销毁视图时在其中卸载模块。
package main
import (
"bufio"
"fmt"
"io"
"log"
"os/exec"
)
func main() {
cmd := exec.Command("sh", "-c",
`for i in $(seq 1 10000); do
echo '{"Name": "Bob", "Age": 32}'
sleep $(( ${RANDOM}%5)) # <<<< Stops before reading all lines when uncommented
done`,
)
stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}
if err := cmd.Start(); err != nil {
log.Fatal(err)
}
printOutput(stdout)
if err := cmd.Wait(); err != nil {
log.Fatal(err)
}
}
func printOutput(r io.Reader) {
scanner := bufio.NewScanner(r)
var x = 1
for scanner.Scan() {
fmt.Println(x, scanner.Text())
x++
}
if err := scanner.Err(); err != nil {
fmt.Println("reading input:", err)
}
}
因此,当卸载模块时,您的单例ViewModel将被破坏。
答案 1 :(得分:0)
您需要阅读有关ViewModel
的更多信息才能更好地理解它。
https://developer.android.com/topic/libraries/architecture/viewmodel
ViewModel
已连接到您的Activity
因此您只能在他的ViewModel
之间共享您的活动Fragments
这就是sharedViewModel
中的koin
sharedViewModel
是相同的,如果您将ViewModel Factory
与相同的context
一起使用。
在Activities
之间共享任何数据都可以通过Intent
完成,Android中没有其他方法,
或者您可以保留一些static / global
数据并在Activities
答案 2 :(得分:0)
在对体系结构级别进行了一些研究或讨论之后,还报告并发布了github Koin,我找到了解决方案 在这种情况下,我们应该将该状态/数据保存到存储库中,我们需要在不在ViewModel中的多个活动之间共享该状态/数据,并且两个或多个不同的ViewModel可以访问保存在存储库单个实例中的相同状态/数据
答案 3 :(得分:0)
我建议将应用程序设为ViewModelStoreOwner
,并以应用程序所有者的身份注入viewModels。
所需的代码如下:
class App : Application(), ViewModelStoreOwner {
private val mViewModelStore = ViewModelStore()
override fun getViewModelStore(): ViewModelStore {
return mViewModelStore
}
}
您可以定义一些扩展以轻松注入viewModels
val Context.app: App
get() = applicationContext as App
inline fun <reified T : ViewModel> Context.appViewModel(
qualifier: Qualifier? = null,
noinline state: BundleDefinition? = null,
noinline parameters: ParametersDefinition? = null
): Lazy<T> {
return lazy(LazyThreadSafetyMode.NONE) {
GlobalContext.get().getViewModel(qualifier, state, { ViewModelOwner.from(app, null) }, T::class, parameters)
}
}
inline fun <reified T : ViewModel> Fragment.appViewModel(
qualifier: Qualifier? = null,
noinline state: BundleDefinition? = null,
noinline parameters: ParametersDefinition? = null
): Lazy<T> {
return lazy(LazyThreadSafetyMode.NONE) {
GlobalContext.get().getViewModel(qualifier, state, { ViewModelOwner.from(requireContext().app, null) }, T::class, parameters)
}
}
然后您可以像这样注入viewModel
class MainActivity : AppCompatActivity() {
private val mAppViewModel: AppViewModel by appViewModel()
}
该解决方案的优势在于您无需重新创建视图模型,并且如果您决定保存应用程序重启之间的状态,则可以轻松地将应用程序设置为SavedStateRegistryOwner
,并使用{ {1}}从viewModel内部保存/恢复状态,现在已绑定到流程生命周期。