Android返回键需多次点击关闭App,Fragment重复重建问题求助
Android应用Fragment重复重建与返回键异常问题
我的Android应用包含带7个Fragment的导航抽屉,在应用启动时,或是从详情Activity返回后,点击返回键会出现Fragment重复重建的情况,并且需要多次点击返回键才能关闭应用。
MainActivity代码
@AndroidEntryPoint class MainActivity : AppCompatActivity() { var APP_START_TIME: Long = 0 private lateinit var appBarConfiguration: AppBarConfiguration private var _binding: ActivityMainBinding? = null private val binding get() = _binding!! private lateinit var navController: NavController private lateinit var postViewModel: PostViewModel private var _navGraph: NavGraph? = null private val navGraph get() = _navGraph!! lateinit var adView: AdView private var adRequest: AdRequest? = null private val applicationScope = CoroutineScope(Dispatchers.Unconfined) override fun onDestroy() { super.onDestroy() adView.destroy() adRequest = null _binding = null } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) APP_START_TIME = System.currentTimeMillis() _binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) adView = AdView(this) delayedInit() postViewModel = ViewModelProvider(this)[PostViewModel:: class.java] setSupportActionBar(binding.toolbar) val drawerLayout: DrawerLayout = binding.drawerLayout val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment? if (navHostFragment != null) { navController = navHostFragment.navController } appBarConfiguration = AppBarConfiguration( setOf( R.id.nav_home, R.id.nav_accessory, R.id.nav_arcade, R.id.nav_fashion, R.id.nav_food, R.id.nav_heath, R.id.nav_lifestyle, R.id.nav_sports, R.id.nav_favorites, R.id.settingsFragment ), drawerLayout ) setupActionBarWithNavController(this, navController, appBarConfiguration) setupWithNavController(binding.navView, navController) _navGraph = navController.navInflater.inflate(R.navigation.mobile_navigation) onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { // Back is pressed... Finishing the activity finish() } }) } // override fun onStart() { // super.onStart() // } override fun onPause() { super.onPause() adView.pause() } override fun onResume() { super.onResume() adView.resume() postViewModel.currentDestination.observe(this) { currentDestination -> Log.w(TAG, "currentDestination: at first run is $currentDestination") navGraph.setStartDestination(currentDestination) navController.graph = navGraph } navController.addOnDestinationChangedListener { _, destination, _ -> Log.d(TAG, "addOnDestinationChangedListener: " + destination.id) if (destination.id != R.id.settingsFragment && destination.id != R.id.aboutFragment && destination.id != R.id.privacyPolicyFragment ) { postViewModel.saveCurrentDestination(destination.id) } } } private fun requestHomeBanner() { adRequest = Constants.callAndBuildAdRequest() adView.adListener = object : AdListener() { override fun onAdFailedToLoad(adError: LoadAdError) { Log.e(TAG, "onAdFailedToLoad: ${adError.cause.toString()}") Log.e(TAG, "onAdFailedToLoad: ${adError.responseInfo.toString()}") } } adRequest?.let { adView.loadAd(it) } } private fun delayedInit() = applicationScope.launch { binding.adViewContainer.addView(adView) adView.adUnitId = "ca-app-pub-3940256099942544/6300978111" adView.setAdSize(Constants.GET_AD_SIZE(this@MainActivity)) val testDeviceIds = listOf("048DC5C3C06FBD17D9AD205151167F48") val configuration = RequestConfiguration.Builder().setTestDeviceIds(testDeviceIds).build() MobileAds.setRequestConfiguration(configuration) if (Utils.hasInternetConnection(this@MainActivity)) { requestTheLatestConsentInformation(this@MainActivity) MobileAds.initialize(this@MainActivity) { Log.d(TAG, "onInitCompleted") } requestHomeBanner() } } override fun onSupportNavigateUp(): Boolean { return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp() } }
尝试过的无效解决方法
- 在
OnBackPressedCallback中添加代码:
navGraph.clear() binding.drawerLayout.removeAllViews() binding.navView.removeAllViews()
- 在
addOnDestinationChangedListener中添加onBackPressedDispatcher回调:
onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { // Back is pressed... Finishing the activity navController.clearBackStack(destination.id) finish() } })
- 在Fragment中处理返回键事件:
requireActivity() .onBackPressedDispatcher .addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { Log.d(TAG, "Fragment back pressed invoked") // hideShimmerEffect() // Do custom work here requireActivity().finish() // if you want onBackPressed() to be called as normal afterwards if (isEnabled) { isEnabled = false requireActivity().onBackPressed() } } })
- 添加出栈或清空回退栈的代码:
findNavController().popBackStack() findNavController().clearBackStack(R.id.nav_home)
- 修改
onSupportNavigateUp方法:
override fun onSupportNavigateUp(): Boolean { return if(supportFragmentManager.backStackEntryCount > 0){ navController.navigateUp(appBarConfiguration) }else { finish() super.onSupportNavigateUp() } }
内容的提问来源于Stack Exchange,提问作者Dr Mido
相关产品推荐
相关产品推荐

