无法在 lifecycleScope 协程中添加片段
Cant add fragment inside of lifecycleScope coroutine
我在我的 activity 的 onCreate
中使用 lifecycleScope.launch
来收集流,但我也试图在范围内附加一个片段,但我只是得到一个黑屏当尝试这样做时,就像它永远不会被附加一样。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
lifecycleScope.launch {
_viewModel.listenForScheduleChanges().flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
}
_viewModel.loadConfig() // suspend method that loads information
_webFragment = WebFragment().apply {
arguments = Bundle().apply {
putParcelable("config", _viewModel.config)
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.contentPanel, _webFragment!!)
.commit()
}
}
如果我不使用 lifecycleScope 并在我的 activity 中使用该协程范围实现 CoroutineScope
,则该片段会很好地附加
class MainActivity : AppCompatActivity(), CoroutineScope{
private val job = SupervisorJob()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
lifecycleScope.launch {
_viewModel.listenForScheduleChanges().flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
}
}
launch {
_viewModel.loadConfig() // suspend method that loads information
_webFragment = WebFragment().apply {
arguments = Bundle().apply {
putParcelable("config", _viewModel.config)
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.contentPanel, _webFragment!!)
.commit()
}
}
}
我不明白为什么,两者似乎都使用与 Main 相同的 Dispatcher 上下文。
有人可以在这里提供见解吗?
将收集数据的代码从流程中分离到另一个协程范围
您的问题将得到解决:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
_viewModel.listenForScheduleChanges().collect {
}
}
}
lifecycleScope.launch {
_viewModel.loadConfig() // suspend method that loads information
_webFragment = WebFragment().apply {
arguments = Bundle().apply {
putParcelable("config", _viewModel.config)
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.contentPanel, _webFragment!!)
.commit()
}
}
问题是,当您以这种方式收集流时,它会阻塞整个范围,并且范围中的其他代码不是 运行。
我在我的 activity 的 onCreate
中使用 lifecycleScope.launch
来收集流,但我也试图在范围内附加一个片段,但我只是得到一个黑屏当尝试这样做时,就像它永远不会被附加一样。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
lifecycleScope.launch {
_viewModel.listenForScheduleChanges().flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
}
_viewModel.loadConfig() // suspend method that loads information
_webFragment = WebFragment().apply {
arguments = Bundle().apply {
putParcelable("config", _viewModel.config)
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.contentPanel, _webFragment!!)
.commit()
}
}
如果我不使用 lifecycleScope 并在我的 activity 中使用该协程范围实现 CoroutineScope
,则该片段会很好地附加
class MainActivity : AppCompatActivity(), CoroutineScope{
private val job = SupervisorJob()
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
lifecycleScope.launch {
_viewModel.listenForScheduleChanges().flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
}
}
launch {
_viewModel.loadConfig() // suspend method that loads information
_webFragment = WebFragment().apply {
arguments = Bundle().apply {
putParcelable("config", _viewModel.config)
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.contentPanel, _webFragment!!)
.commit()
}
}
}
我不明白为什么,两者似乎都使用与 Main 相同的 Dispatcher 上下文。
有人可以在这里提供见解吗?
将收集数据的代码从流程中分离到另一个协程范围 您的问题将得到解决:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
_viewModel.listenForScheduleChanges().collect {
}
}
}
lifecycleScope.launch {
_viewModel.loadConfig() // suspend method that loads information
_webFragment = WebFragment().apply {
arguments = Bundle().apply {
putParcelable("config", _viewModel.config)
}
}
supportFragmentManager.beginTransaction()
.replace(R.id.contentPanel, _webFragment!!)
.commit()
}
}
问题是,当您以这种方式收集流时,它会阻塞整个范围,并且范围中的其他代码不是 运行。