我的MainActivity中有一个使用导航图的FragmentContainerView。
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav" />
我希望我的片段在我隐藏闪屏之前等待,直到我从API获得一些数据。我使用的是android 12 Splash Screen。这是我尝试实现它的方式(来自文档):
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
setContentView(R.layout.activity_main)
//Set up an OnPreDrawListener to the root view.
val content: View = findViewById(android.R.id.content)
content.viewTreeObserver.addOnPreDrawListener(
object : ViewTreeObserver.OnPreDrawListener {
override fun onPreDraw(): Boolean {
// Check if the initial data is ready.
return if (mainActivityViewModel.isDataReady()) {
// The content is ready; start drawing.
Timber.tag("Splash").d("data ready")
content.viewTreeObserver.removeOnPreDrawListener(this)
true
} else {
Timber.tag("Splash").d("data not ready")
// The content is not ready; suspend.
false
}
}
}
)
启动画面只有在我取得数据后才会消失。但问题是我的片段回呼(如onViewCreated
)在我的数据准备好之前就被叫用了。这会造成问题,因为我依赖于在启动画面期间取得的数据来执行某些工作。
我如何确保在闪屏消失之前我的片段不会被初始化?
1条答案
按热度按时间kt06eoxx1#
Splash屏幕只有在我获得数据后才会消失,但问题是我的Fragments回调(如onViewCreated)甚至在数据准备好之前就被调用了。
Activity和fragment生命周期回调只能由系统在适当的时间触发,开发人员不能触发;因此,你不能阻止
onCreateView
,onViewCreated
,..的发生,也就是说,你不能阻止活动/片段的初始化;否则你可能会有ANR。更多详细信息
在某些后台任务完成之前,不应获取活动/片段的初始化;这实际上将导致ANR。
当您使用
addOnPreDrawListener
获取Activity的根布局的绘图时;这并不意味着Activity的初始化(即onCreate()
)被占用,因为两者都是异步工作的,并且onCreate()
、onStart()
和onResume()
将正常返回。对于片段的回调也是如此,其中片段的初始化(即
onCreateView()
、onViewCreated
...)与Activity的onCreate()
耦合。现在,由于起始目的地片段的初始化依赖于API数据;则该特定片段不应该是起始目的地。
因此,要解决这个问题,您需要创建一个不依赖于API数据的启动屏幕片段作为启动目标。
根据API传入的数据,您可以决定通过
navController
: