如何从Fragment向非其容器的Activity传递数据,现有实现无响应如何解决
问题根因
- 你当前的实现逻辑完全用错了通信方式:
(activity as? IProfileToActivity)强转的是当前Fragment依附的宿主Activity,而不是你要启动的ProfileActivity,宿主Activity没有实现IProfileToActivity接口,所以强转结果为null,profileInfo方法根本不会执行,自然没有任何响应。 - 退一步说,即便你能拿到
ProfileActivity的实例,在startActivity执行前调用它的成员方法也没有意义,此时目标Activity还没走初始化生命周期,myBinding还未赋值,强行调用只会触发空指针崩溃。 - 接口回调的适用场景是Fragment和它当前已依附的宿主Activity通信,不适用于跨未启动的新Activity传参。
正确实现方案
跨Activity传参直接使用Android原生的Intent携带参数即可,操作步骤如下:
- 先给传递的数据类实现序列化接口,推荐使用Android性能更优的
Parcelable:
- 首先在module级的
build.gradle中添加Parcelize插件:
plugins { // 其他已有插件 id 'kotlin-parcelize' }
- 给
AllHeroes.Global添加Parcelable注解:
import kotlinx.parcelize.Parcelize import android.os.Parcelable @Parcelize data class AllHeroes( val global: Global ) { @Parcelize data class Global( val name: String, val rank: Rank // 其余字段按实际补充 ): Parcelable @Parcelize data class Rank( val rankName: String // 其余字段按实际补充 ): Parcelable }
- 修改Fragment的点击事件,将数据塞入Intent:
override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId){ R.id.action_profile -> { val intent = Intent(requireActivity(), ProfileActivity::class.java) // 以键值对形式存入数据,key可自定义,保证存取一致即可 intent.putExtra("PROFILE_INFO", testApex) startActivity(intent) return true } } return super.onOptionsItemSelected(item) }
- 目标
ProfileActivity中直接从Intent取出数据即可,不需要实现自定义接口:
class ProfileActivity : AppCompatActivity() { private lateinit var myBinding: ActivityProfileBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) myBinding = ActivityProfileBinding.inflate(layoutInflater) setContentView(myBinding.root) // 取出传递的数据 val profileData = intent.getParcelableExtra<AllHeroes.Global>("PROFILE_INFO") profileData?.let { data -> myBinding.tvUsername.text = data.name myBinding.tvDivision.text = data.rank.rankName Log.i("Apex Info 3", data.toString()) } } }
注意事项
如果传递的数据体积超过1MB,不要使用Intent传参,避免触发Binder事务大小限制的崩溃,可改用本地SP缓存、全局ViewModel存储等方案实现。
内容的提问来源于stack exchange,提问作者Ethernets
相关产品推荐
相关产品推荐

