Android应用切换底部导航崩溃:未使用setReorderingAllowed(true)
问题
Android应用中,HomeActivity带有底部菜单导航,可打开对应的Fragment。Fragment内部导航正常,但从该Fragment点击其他底部导航项时应用立即崩溃,抛出如下错误:
2022-12-07 10:39:41.828 8956-8956 AndroidRuntime pid-8956 E FATAL EXCEPTION: main Process: com.my.app.debug, PID: 8956 java.lang.IllegalArgumentException: saveBackStack("f1a147ba-4bb3-449c-87b8-cf73f7bf463c") included FragmentTransactions must use setReorderingAllowed(true) to ensure that the back stack can be restored as an atomic operation. Found BackStackEntry{82b1a #1} that did not use setReorderingAllowed(true). at androidx.fragment.app.FragmentManager.saveBackStackState(FragmentManager.java:2141) at androidx.fragment.app.FragmentManager$SaveBackStackState.generateOps(FragmentManager.java:3494) at androidx.fragment.app.FragmentManager.generateOpsForPendingActions(FragmentManager.java:2067) at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1757) at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:547) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
已尝试以下方法,但均无效:
- 在Fragment的
onCreateView()中复用视图:
if (fragmentView != null) { return fragmentView; }
- 在Fragment的
onResume()中添加上下文获取逻辑:
var mContext: FragmentActivity? = FragmentActivity() mContext = this!!.getActivity() as HomeActivity mContext.bottomItems()
相关代码说明:
首页点击底部导航会打开FirstFragment,FirstFragment包含多个标签页,其中SecondFragment会在FirstFragment.kt的observeResponse()方法中被调用加载。
HomeActivity.kt
class HomeActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener { private lateinit var navController: NavController private lateinit var appBarConfiguration: AppBarConfiguration private lateinit var sfHelper: SharedPrefHelper private var mCacheManager: CacheManager? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) mCacheManager = CacheManager(this) sfHelper = SharedPrefHelper(this) val mainActivityIntent: Intent = Intent(this, MainActivity::class.java) mainActivityIntent.putExtra("navigateScreen", intent.getStringExtra("navigateScreen")) startActivity(mainActivityIntent) finishAffinity() setContentView(R.layout.activity_dashboard) try { navController = findNavController(R.id.fragment_container) appBarConfiguration = AppBarConfiguration.Builder(R.id.homeFragment) .setDrawerLayout(main_drawer_layout) .build() if (mCacheManager!!.isShortCut()) { when (mCacheManager!!.getShortCutName()) { "firstFrag" -> { navController.navigate(R.id.homeFragment_to_firstFragment) ClearCache.cacheManagerClear(this) } } } } catch (e: Exception) { } } private fun setupNavControl() { bottom_navigation?.setupWithNavController(navController) main_navigation_view?.setupWithNavController(navController) } private fun showBothNavigation() { bottom_navigation?.visibility = View.VISIBLE main_navigation_view?.visibility = View.VISIBLE main_drawer_layout?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) setupNavControl() } override fun onSupportNavigateUp(): Boolean { return NavigationUI.navigateUp(navController, appBarConfiguration) } override fun onBackPressed() { when { main_drawer_layout.isDrawerOpen(GravityCompat.START) -> { main_drawer_layout.closeDrawer(GravityCompat.START) } else -> { super.onBackPressed() } } } }
HomeFragment.kt
class HomeFragment : Fragment(), View.OnClickListener { private lateinit var appContext: Context private var fragmentView: View? = null lateinit var sharedPref: SharedPrefHelper override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { if (fragmentView != null) { return fragmentView; } sharedPref = SharedPrefHelper(context as Activity) val view: View = layoutInflater.inflate(R.layout.fragment_home, container, false) fragmentView = view return view } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) loadViewCreated() } private fun loadViewCreated() { try { sharedPref = SharedPrefHelper(context as Activity) appContext = (context as Activity).applicationContext if (user == true) { cButton.setOnClickListener(this) Glide.with(context as Activity).load(R.drawable.preloader_gif).into(loadingViewHome) } else { maLogger.info("HomeFragment", "onViewCreated", "MainApplication.model is null") } } catch (e: Exception) { maLogger.error("HomeFragment", "onViewCreated", e.message.toString()) ExceptionHandler.errorHandle(context as Activity, e.message.toString()) } } @SuppressLint("ResourceAsColor") override fun onClick(v: View?) { when (v!!.id) { R.id.cButton -> { Navigation.findNavController(v) .navigate(HomeFragmentDirections.homeFragment_to_firstFragment()) } } } fun observeModel(viewModel: HomeViewModel) { viewModel.response.observe(viewLifecycleOwner, Observer { it?.let { if (activeUser == true) { } } } } }
FirstFragment.kt
class FirstFragment : Fragment(), View.OnClickListener { lateinit var cView: View private lateinit var cViewModel: CViewModel private var isRotating: Boolean = false private lateinit var rViewModel: rViewModel private lateinit var sfHelper: SharedPrefHelper var user = false override fun onCreateView( inflater: LayoutInflater, @Nullable container: ViewGroup?, @Nullable savedInstanceState: Bundle? ): View? { retainInstance = true if (savedInstanceState == null) { sfHelper = SharedPrefHelper(context as Activity) cView = inflater.inflate(R.layout.fragment_first, container, false) } return cView } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) retainInstance = true if (sfHelper!!.getValueBoolean("SORTING", defaultValue = false) == true) { if (savedInstanceState == null) { loadData() } else { if (MainApplication.isRotating == 1) { loadData() } } } else { sortingPopUp() } } private fun sortingPopUp() { val mDialog = Dialog(context as Activity, android.R.style.Theme_Black_NoTitleBar) mDialog.window?.setBackgroundDrawable(ColorDrawable(Color.argb(100, 0, 0, 0))) mDialog.setContentView(R.layout.sorting) mDialog.setCancelable(false) mDialog.show() mDialog.findViewById<Button>(R.id.btn_got_it).setOnClickListener { sfHelper.save("SORTING", true) mDialog.dismiss() if (NetworkConnectivity.checkNetwork(context as Activity)) { loadData() } else { ExceptionHandler.noInternetAlert(context as Activity) } } } private fun loadData() { if (MainApplication.backClick == 1 || MainApplication.isRotating == 1) { var mContext: FragmentActivity? = FragmentActivity() mContext = this!!.getActivity() as HomeActivity mContext.bottomItems() } rViewModel = ViewModelProviders.of(this).get(rViewModel::class.java) try { var cList = MainApplication.switchList if (MainApplication.isActive) { if (MainApplication.active_model != null) { } } else { } if (cList.size != null) { for (i in 0 until cList.size) { try { } } catch (e: Exception) { e.printStackTrace() } } } catch (e: Exception) { } } override fun onClick(v: View?) { when (v!!.id) { } } private fun observeResponse() { try { cViewModel.response.observe(viewLifecycleOwner, Observer { it?.let { fragmentManager?.beginTransaction() ?.replace(R.id.root_container, SecondFragment()) ?.addToBackStack(null)?.commit() } }) } catch (e: Exception) { } } override fun onSaveInstanceState(outState: Bundle) { if (isRotating) { MainApplication.isRotating = 1 outState.putBoolean("isRotating", true) } super.onSaveInstanceState(outState) } override fun onStop() { super.onStop() } override fun onStart() { super.onStart() if (MainApplication.backClick == 1) { isRotating = true loadData() } else if (MainApplication.isRotating == 1) { isRotating = true loadData() } } override fun onResume() { super.onResume() var mContext: FragmentActivity? = FragmentActivity() mContext = this!!.getActivity() as HomeActivity mContext.bottomItems() if (MainApplication.backClick == 1) { root_container.removeAllViews() MainApplication.backClick = 0 } if (MainApplication.isRotating == 1) { root_container.removeAllViews() MainApplication.isRotating = 0 } } }
内容的提问来源于stack exchange,提问作者LionKing
相关产品推荐
相关产品推荐

