从 Activity 导航到 Fragment 并返回到 Activity 导致该 Activity 被多次创建
Posted
技术标签:
【中文标题】从 Activity 导航到 Fragment 并返回到 Activity 导致该 Activity 被多次创建【英文标题】:Navigation to Fragment from Activity and back to the Activity is causing the activity to be created multiple times 【发布时间】:2021-10-27 14:26:42 【问题描述】:我遇到的问题似乎很奇怪。
言辞
我有一个底部导航菜单的应用程序,其中包含 3 个按钮、每个按钮的 3 个片段和一个 MainActivity。当导航到任何这些片段时,一切都按预期工作。 当我从这 3 个片段中的任何一个导航到另一个片段(我们称之为片段 4 或 fr4)时,就会出现问题。 假设我在 fr1,我有一个按钮可以将我带到 fr4。当我回到 fr1(使用 android 后退按钮或按下 fr1 的底部栏按钮)时,我在主要活动或 3 个片段中的任何一个中所做的每件事都会重复 2 次。如果我再去fr4,然后再回到fr1,那么一切都会重复3次,依此类推。
在下面的代码中,fr1 是 fragment_home,fr4 是 fragment_profile。
代码
MainActivity.kt
class MainActivity : AppCompatActivity()
private lateinit var navView: BottomNavigationView
private lateinit var binding: ActivityMainBinding
private val sharedViewModel: SharedViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
navView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
navView.setupWithNavController(navController)
override fun onStart()
super.onStart()
Timber.i("onStart main activity")
override fun onStop()
super.onStop()
Timber.i("onStop main activity")
framgnet1.kt
class HomeFragment : Fragment()
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
private val sharedViewModel: SharedViewModel by activityViewModels()
private val homeViewModel: HomeViewModel by viewModels()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
_binding = FragmentHomeBinding.inflate(inflater, container, false)
val root: View = binding.root
binding.lifecycleOwner = viewLifecycleOwner
binding.sharedViewModel = sharedViewModel
binding.homeViewModel = homeViewModel
binding.historyButton.setOnClickListener
Timber.i("profile button clicked")
binding.profileButton.setOnClickListener view ->
profileButtonClicked(view)
return root
fun profileButtonClicked()
Timber.i("profile button clicked")
val action = HomeFragmentDirections.homeToProfileAction()
NavHostFragment.findNavController(this).navigate(action)
mobile_navigation.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/navigation_home">
<fragment
android:id="@+id/navigation_home"
android:name="com.comp.comp.ui.home.HomeFragment"
android:label="@string/title_home"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/home_to_profile_action"
app:destination="@id/fragment_profile"
app:launchSingleTop="true" />
</fragment>
<fragment
android:id="@+id/navigation_dashboard"
android:name="com.comp.comp.ui.dashboard.DashboardFragment"
android:label="@string/title_dashboard"
tools:layout="@layout/fragment_dashboard" >
</fragment>
<fragment
android:id="@+id/navigation_notifications"
android:name="com.comp.comp.ui.notifications.NotificationsFragment"
android:label="@string/title_notifications"
tools:layout="@layout/fragment_notifications" />
<fragment
android:id="@+id/fragment_profile"
android:name="com.comp.comp.fragment_profile"
android:label="fragment_profile"
tools:layout="@layout/fragment_profile" />
</navigation>
我尝试在导航操作上切换 launchSingleTop="true"
无济于事。
会发生以下情况:
-
在主页片段中,如果我按下历史按钮,它会打印一次“点击个人资料按钮”
如果我随后点击个人资料按钮,应用程序将导航到个人资料片段
我可以使用返回按钮或按下底部栏上的主页按钮返回主页片段
如果我现在按下历史按钮,“点击的配置文件按钮”会打印两次。
如果我重复上述步骤,那么下次我按下历史按钮时,它将打印“点击个人资料按钮”3 次,依此类推。
我还测试过转到另一个活动,如果我以前去过个人资料页面一次,我的主要活动中的onStop()
方法也会运行两次。当我回到主要活动时,onStart()
方法运行两次。根据我进入个人资料页面的次数,我所做的一切都会运行 2 次(或更多)。每次我访问同时存在的个人资料页面时,它似乎都会创建一个主要活动。任何想法为什么?
【问题讨论】:
【参考方案1】:我尝试了一切都无济于事。然后我意识到,在每次配置更改时,它都会种植一个新的 Jake Wharton 的 Timber 调试树,并且它会记录尽可能多的树的所有内容。 希望这可以帮助某人。我的错误是木材刨在 MainActivity 的 onCreate 中,而它应该在 Application 的 OnCreate 中。
【讨论】:
以上是关于从 Activity 导航到 Fragment 并返回到 Activity 导致该 Activity 被多次创建的主要内容,如果未能解决你的问题,请参考以下文章
使用 Activity 的工具栏从 Fragment 向上导航
(导航组件)返回首页fragment时如何在activity上显示返回箭头?
如何在 JetPack Navigation 组件中托管 Fragment 的 Activity 中调用导航 Fragments 函数?
Kotlin:是不是可以从 Activity-1 的 Fragment 移动到 Activity-2