gpt4 book ai didi

android - IllegalStateException onSaveInstanceState 显示 DialogFragment 后无法执行此操作

转载 作者:行者123 更新时间:2023-12-03 08:34:33 25 4
gpt4 key购买 nike

这是我第一次遇到这个问题。

我已经仔细查看了 SO 上的几个答案,尤其是 this onethis one但它并没有解决我的问题,并且大多数答案都不能用作解决我的案例的安全可靠的方法。

我已经尝试过:

  • 覆盖onSaveInstanceState并且不调用super

但是 commitAllowingStateLoss 不能用于第一种情况。

我正在寻找有关如何避免引发此异常以及如何实现引发异常的操作的解释(在第一种情况下,显示dialogFragment)。我已经知道如何引发此异常,但是,我不知道在我的情况下引发了什么。它在我的应用程序中出现两次:

第一个发生在一个非常简单的 Activity 中,我有一个简单的动画,在该动画结束时我显示了一个 DialogFragment (SplashActivity):

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val potentialLanguage = storage.getString(Constants.LANGUAGE)
val lang = if (potentialLanguage.isNotEmpty()) {
potentialLanguage
} else {
Locale.getDefault().language
}
val language = Language.getFromName(lang)!!
val dm = res.displayMetrics
val conf = res.configuration
conf.setLocale(Locale(language))
saveLanguage(context, lang)
// Use conf.locale = new Locale(...) if targeting lower versions
res.updateConfiguration(conf, dm)
initWarningDialog()
RevelyGradient
.radial()
.colors(
intArrayOf(
getColor(R.color.backgroundOnBoardingStart),
getColor(R.color.backgroundOnBoardingEnd)
)
)
.onBackgroundOf(root)
ivCap.animate()
.alpha(1f)
.setListener(object : Animator.AnimatorListener{
override fun onAnimationEnd(p0: Animator?) {
try {
commonDialog.show(supportFragmentManager, "CommonDialogSplash") //crash here commonDialog is a DialogFragment
}
catch (e: IllegalStateException){
try {
startActivity(Intent(this@SplashActivity, MainActivity::class.java))
finish()
}
catch (e: IllegalStateException){

}
}
}

override fun onAnimationCancel(p0: Animator?) {

}

override fun onAnimationRepeat(p0: Animator?) {

}

override fun onAnimationStart(p0: Animator?) {

}
}).duration = 1000
}

private fun initWarningDialog(){
commonDialog.isCancelable = false
commonDialog.setTitle(getString(R.string.warning))
commonDialog.setFirstTextButton(getString(R.string.ok))
commonDialog.setDescription(getString(R.string.warning_message))
commonDialog.setFirstButtonListener(object : CommonDialog.CommonDialogClickListener {
override fun onClick() {
commonDialog.dismiss()
startActivity(Intent(this@SplashActivity, MainActivity::class.java))
finish()
}
})
}

第二个是当我尝试在 firebase firestore 请求(TotoFragment)之后添加 fragment 时:

fun pullChallenges(){
val db = Firebase.firestore
val docRef = db.collection("challenges").document(language.name.toLowerCase(Locale.ROOT))
docRef
.get()
.addOnSuccessListener { result ->
result.data?.let {data ->
data.values.map {values->
val alOfHm = values as ArrayList<HashMap<String, String>>
for (item in alOfHm){
val challenge = Challenge()
Challenge.ChallengeCategory.getValueOf(item["category"]!!)?.let {
challenge.challengeCategory = it
}
Game.GameMode.getValueOf(item["mode"]!!)?.let {
challenge.mode = it
}
challenge.challenge = item["content"]!!
challenges.add(challenge)
}
}
}
ChallengesManager.challenges = challenges
listener.onChallengesReady(true)
}
.addOnFailureListener { exception ->
listener.onChallengesReady(false)
Timber.e("Error getting challenges $exception")
}
}

override fun onChallengesReady(success: Boolean) {
renderLoading()
if (success) {
try {
goToChooseMode()
}
catch (e: IllegalStateException){

}
}
else {
Toast.makeText(requireContext(), getString(R.string.error_get_caps), Toast.LENGTH_SHORT).show()
}
}

private fun goToChooseMode(){
val bundle = Bundle()
bundle.putStringArrayList(Constants.PLAYERS, ArrayList(viewModel.players))
activity.supportFragmentManager
.beginTransaction()
.addToBackStack(ChooseModeFragment::class.java.name)
.setReorderingAllowed(true)
.add(R.id.fragmentContainer, ChooseModeFragment::class.java, bundle, ChooseModeFragment::class.java.name)
.commit()
}

对理解这个问题有任何帮助(对于问题的想法,或者对问题的一些解释,或者快速解决......)

最佳答案

保存状态的目的是,用户可以离开某个应用程序,稍后返回时会发现该应用程序的状态与他离开时的状态完全相同,因此他可以像什么都没发生一样继续操作。在后台,Android 可以终止您的应用以释放资源,但用户不必知道这一点。

Android 已经为您做了很多状态保存,例如您添加的 fragment 。原因IllegalStateException抛出的是你添加一个 Fragment其状态已被保存后,因此其状态无法再次完全恢复。在这两种情况下,您都会启动后台任务,并且当您“回电”时,用户已经导航离开(或进行了配置更改,例如旋转设备)。

要处理此类情况,您可以:

  1. 提交您的FragmentTransaction允许状态丢失 commitAllowingStateLoss() 。请注意,不要调用 show()在您的DialogFragment上你可以自己做FragmentTransaction ,因为show()正是这样做的,请参阅源代码。
  2. 在执行 FragmentTransaction 之前检查状态是否已保存通过调用 isStateSaved()在您的FragmentManager上.

解决方案 #2(无状态丢失)比 #1 更好,但它确实要求您在配置更改时从 FireStore 获取数据两次。更现代的方法将使用 ViewModel保存您的数据,因此您只需要获取一次数据(在配置更改时)。这是因为ViewModelFragment 具有更长(且非常方便)的生命周期.

关于android - IllegalStateException onSaveInstanceState 显示 DialogFragment 后无法执行此操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64316430/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com