清空back stack后跳转
wsdydeni opened this issue · 6 comments
在看了这篇文章之后,里面有一个写法,目标是和标题一样,行为应该是切换了navigation
和startDestination
。
<?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"
android:id="@+id/main_navigation"
app:startDestination="@id/home_fragment">
<action
android:id="@+id/action_login"
app:destination="@+id/login_navigation"
app:popUpTo="@id/main_navigation"
app:popUpToInclusive="true"
app:launchSingleTop="true"/>
<fragment
android:id="@+id/home_fragment"
android:name="com.example.HomeFragment" />
<navigation
android:id="@+id/login_navigation"
app:startDestination="@id/login_fragment">
<fragment
android:id="@+id/login_fragment"
android:name="com.example.LoginFragment" />
</navigation>
</navigation>
结果发生了问题,对大佬的严格深有感悟,受制于自身水平,实在没办法探索。
2022-01-18 12:22:03.157 E/AndroidRuntime: FATAL EXCEPTION: main
Process: , PID: 16247
java.lang.RuntimeException: Unable to start activity ComponentInfo{/*******.module.main.mine.bankcard.BankCardManagerActivity}: java.lang.UnsupportedOperationException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2877)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2938)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1652)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6441)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:939)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:829)
Caused by: java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:161)
at androidx.navigation.fragment.FragmentNavigator.popBackStack(FragmentNavigator.java:109)
at androidx.navigation.NavController.popBackStackInternal(NavController.java:323)
at androidx.navigation.NavController.navigate(NavController.java:1059)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.NavController.navigate(NavController.java:863)
at androidx.navigation.NavController.navigate(NavController.java:851)
at **************.module.main.mine.bankcard.BankCardManagerActivity.initView(BankCardManagerActivity.kt:30)
at com.wsdydeni.baselib.base.BaseActivity.onCreate(BaseActivity.kt:46)
at android.app.Activity.performCreate(Activity.java:6782)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2825)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2938)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1652)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6441)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:939)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:829)
具体是 FragmentNavigator.java:109
boolean isSingleTopReplacement = navOptions != null && !initialNavigation && navOptions.shouldLaunchSingleTop() && (Integer)this.mBackStack.peekLast() == destId;
出现了一样的报错,需求是在启动一个activity时 动态判断 设置 setStartDestination(),如果在oncreate就报上面的错,如果是onstart()就同过,个人理解是初始化未完成就开始清理栈。问题是之前的项目没有出现。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// val binding = ActivityMainBinding.inflate(layoutInflater)
// setContentView(binding.root)
setContentView(R.layout.activity_main)
initNavGraph()
}
override fun onStart() {
super.onStart()
initNavGraph()
}
private fun initNavGraph() {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_main) as NavHostFragment
navHostFragment.navController
val navController = navHostFragment.navController
val navMainGraph = navController.navInflater.inflate(R.navigation.nav_main)
//TODO 数据不应该直接出现在UI,这个模式数据应该放在 ShareViewModel 中 区局多次使用
//判断是否已经选择了指定对讲模式,如果没有选择就显示选择对讲模式页,如果已经存在,直接进入对应的对讲主页
val selectcallModeInt = AppConfigs.selectCallModeKVI.get()
val startDestinationId = if (selectcallModeInt == -1) {
R.id.selectModeFragment
} else {
// R.id.homeFragment
R.id.selectModeFragment
}
navMainGraph.setStartDestination(startDestinationId)
navController.graph = navMainGraph
}
出现了一样的报错,需求是在启动一个activity时 动态判断 设置 setStartDestination(),如果在oncreate就报上面的错,如果是onstart()就同过,个人理解是初始化未完成就开始清理栈。问题是之前的项目没有出现。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // val binding = ActivityMainBinding.inflate(layoutInflater) // setContentView(binding.root) setContentView(R.layout.activity_main) initNavGraph() }
override fun onStart() { super.onStart() initNavGraph() } private fun initNavGraph() { val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_main) as NavHostFragment navHostFragment.navController val navController = navHostFragment.navController val navMainGraph = navController.navInflater.inflate(R.navigation.nav_main) //TODO 数据不应该直接出现在UI,这个模式数据应该放在 ShareViewModel 中 区局多次使用 //判断是否已经选择了指定对讲模式,如果没有选择就显示选择对讲模式页,如果已经存在,直接进入对应的对讲主页 val selectcallModeInt = AppConfigs.selectCallModeKVI.get() val startDestinationId = if (selectcallModeInt == -1) { R.id.selectModeFragment } else {
// R.id.homeFragment R.id.selectModeFragment } navMainGraph.setStartDestination(startDestinationId) navController.graph = navMainGraph
}
兄弟 你需要换种写法来获取NavController
出现了一样的报错,需求是在启动一个activity时 动态判断 设置 setStartDestination(),如果在oncreate就报上面的错,如果是onstart()就同过,个人理解是初始化未完成就开始清理栈。问题是之前的项目没有出现。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // val binding = ActivityMainBinding.inflate(layoutInflater) // setContentView(binding.root) setContentView(R.layout.activity_main) initNavGraph() }override fun onStart() { super.onStart() initNavGraph() } private fun initNavGraph() { val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_main) as NavHostFragment navHostFragment.navController val navController = navHostFragment.navController val navMainGraph = navController.navInflater.inflate(R.navigation.nav_main) //TODO 数据不应该直接出现在UI,这个模式数据应该放在 ShareViewModel 中 区局多次使用 //判断是否已经选择了指定对讲模式,如果没有选择就显示选择对讲模式页,如果已经存在,直接进入对应的对讲主页 val selectcallModeInt = AppConfigs.selectCallModeKVI.get() val startDestinationId = if (selectcallModeInt == -1) { R.id.selectModeFragment } else {
// R.id.homeFragment R.id.selectModeFragment } navMainGraph.setStartDestination(startDestinationId) navController.graph = navMainGraph
}
兄弟 你需要换种写法来获取NavController
具体怎么写?麻烦了
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
lifecycleScope.launch {
//如果不加延迟就报错,加了就正常了
//java.lang.UnsupportedOperationException
// at java.util.AbstractList.remove(AbstractList.java:161)
// at androidx.navigation.fragment.FragmentNavigator.popBackStack(FragmentNavigator.java:109)
// delay(2)
initNavGraph()
}
}
private fun initNavGraph() {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_main) as NavHostFragment
val navController = navHostFragment.navController
val navMainGraph = navController.navInflater.inflate(R.navigation.nav_main)
navMainGraph.setStartDestination(R.id.homeFragment)
navController.graph = navMainGraph
}
}
延迟 1微秒就不报错了
换了Navigation.findNavController 也是一样,延迟1毫秒就不报错,不延迟就报错,不知道有正解不?麻烦了
private fun initNavGraph2() {
val navController = Navigation.findNavController(this, R.id.nav_host_main)
val navMainGraph = navController.navInflater.inflate(R.navigation.nav_main)
navMainGraph.setStartDestination(R.id.homeFragment)
navController.graph = navMainGraph
}
给你翻了下代码
val navHostFragment = supportFragmentManager
.findFragmentById(R.id.nav_host_fragment_bankcard) as NavHostFragment
val navController = NavHostFragment.findNavController(navHostFragment)
val bankCardCount = intent?.getIntExtra("bankCardCount",0)
navController.setGraph(
if(bankCardCount == 0) R.navigation.nav_bankcard_add
else R.navigation.nav_bankcard,
// 没有银行卡时,添加银行卡界面直接退出
if(bankCardCount == 0) Bundle().apply { putBoolean("isReturnList",false) }
else null
)
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_host_fragment_bankcard"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
/>