Kotlin中从InstructionsFragment正确启动ShoeListActivity2的方法
解决Fragment启动Activity时跳转错误的问题
项目背景
项目包为com.udacity.shoestore,包含组件:
- MainActivity
- ShoeListActivity2
- ShoeListFragment2
- WelcomeFragment
- InstructionsFragment
布局文件包括activity_main、activity_shoe_list2、fragment_instructions等。
当前Manifest中Activity的关键配置:
<activity android:name=".ShoeListActivity2" android:exported="false" android:label="@string/title_activity_shoe_list2" android:theme="@style/AppTheme.NoActionBar.NoActionBar" > <intent-filter> <action android:name="android.intent.action.MAIN"/> </intent-filter> </activity> ... <activity android:name=".MainActivity" android:exported="true" android:screenOrientation="unspecified"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
问题现象
从InstructionsFragment启动ShoeListActivity2时崩溃,调试发现系统尝试加载MainActivity,先后尝试四种写法均失败:
- IDE不识别Intent构造:
binding.listShoesButton.setOnClickListener { val intent=Intent(this@InstructionsFragment, this@ShoeListActivity2) startActivity(intent) }
- 无法通过编译:
val intent = Intent(ACTION_MAIN) startActivity(intent, ShoeListActivity2::class.java)
- 执行后先跳转MainActivity再崩溃:
binding.listShoesButton.setOnClickListener { val intent = Intent(context, ShoeListActivity2::class.java) startActivity(intent) }
- 编辑器标记Intent为错误:
binding.listShoesButton.setOnClickListener { val intent = Intent(this@InstructionsFragment, ShoeListActivity2::class.java) startActivity(intent) }
问题根源
ShoeListActivity2的Manifest配置错误:给它添加了<action android:name="android.intent.action.MAIN"/>的intent-filter,这个action用于标记应用的入口Activity。当系统处理跳转请求时,会匹配所有带有MAIN action的Activity,而MainActivity同时带有LAUNCHER category,被系统判定为优先入口,导致跳转逻辑混乱。
解决方案
1. 修正Manifest配置
移除ShoeListActivity2中的<intent-filter>,它不需要作为应用入口,修正后代码:
<activity android:name=".ShoeListActivity2" android:exported="false" android:label="@string/title_activity_shoe_list2" android:theme="@style/AppTheme.NoActionBar.NoActionBar" />
2. 使用正确的显式Intent启动Activity
在InstructionsFragment中,使用requireContext()获取安全的上下文(避免空指针),创建显式Intent:
binding.listShoesButton.setOnClickListener { val intent = Intent(requireContext(), ShoeListActivity2::class.java) startActivity(intent) }
说明:
requireContext()会返回非空的Context,符合Kotlin空安全规范,比直接使用context更可靠。- 显式Intent直接指定目标Activity的class,不会触发系统的隐式匹配逻辑,确保精准跳转。
内容的提问来源于stack exchange,提问作者Philip Stephens
相关产品推荐
相关产品推荐

