A HomeActivity class has a bottom menu navigation which opens up a fragment class. Everything is good to navigate inside the fragment class. However, when I click any other bottom menu navigation item from this fragment class, it immediately crashes and results with the below error,
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)
In my fragment class, I tried to return the same view in onCreateView()
if (fragmentView != null) {
return fragmentView;
}
Also added 'context' in onResume() for my fragment class
var mContext: FragmentActivity? = FragmentActivity()
mContext = this!!.getActivity() as HomeActivity
mContext.bottomItems()
and nothing worked so far. With this log information couldn't find much on where and what exactly went wrong.
I found this Stack overflow link app-crashes-when-tapping-multiple-times-on-bottom-navigation-views that somewhat relates to my issue however the error between mine and this link is different here
Found BackStackEntry{82b1a #1} that did not use setReorderingAllowed(true).
Adding Code
For Understanding, From Home screen user clicks the bottom navigation which shows the FirstFragment screen. The Firstfragment contains few tabviews where you see the SecondFragment information called in observeResponse()
method in the class FirstFragment.kt
being called will get loaded.
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
}
}
}