You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中Activity能否使用newInstance()及Fragment实例化报错解决

核心问题梳理

  • 抽象类FragmentA不需要实现newInstance():抽象类本身无法被实例化,给它加创建实例的方法完全没有意义,直接删除这部分伴生对象代码即可。
  • Fragment禁止通过构造函数传参:Android系统在内存不足等场景下会销毁并重建Fragment,重建时只会调用Fragment的无参构造函数,你自定义了带参数的构造函数、没有保留无参构造,就会抛出你遇到的NoSuchMethodException: <init> []报错。
  • Activity不需要写newInstance():Activity的实例化由系统负责,你手动写的创建方法不会被系统调用,完全无用,直接删除即可。
  • 直接把Activity实例传入Fragment会导致内存泄漏,属于错误用法,Fragment需要关联的Context/Activity时,可以通过requireContext()、requireActivity()方法直接获取,不需要传参。

最优解决方案

按照官方规范实现FragmentB的newInstance(),参数通过Bundle传递,系统重建时Bundle会被保留,不会丢失参数。

修正后的FragmentA.kt

abstract class FragmentA: BottomSheetDialogFragment() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setStyle(DialogFragment.STYLE_NORMAL, getStyle)
    }
}

修正后的FragmentB.kt

class FragmentB : FragmentA() {
    // 定义接收参数的变量
    private lateinit var parameterss: AnyParametersHere

    companion object {
        private const val ARG_PARAM = "arg_param"
        const val TAG = "FragmentB"

        // newInstance接收参数,存入Bundle
        fun newInstance(param: AnyParametersHere): FragmentB {
            val fragment = FragmentB()
            val args = Bundle()
            args.putParcelable(ARG_PARAM, param) // 如果是自定义类型要实现Parcelable接口
            fragment.arguments = args
            return fragment
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 从arguments中取出参数
        arguments?.let {
            parameterss = it.getParcelable(ARG_PARAM)!!
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState)
        // 原有逻辑不变,直接用parameterss变量即可
        return dialog
    }
}

修正后的MainActivity.kt

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 用newInstance创建Fragment,传入需要的参数
        val fragmentB = FragmentB.newInstance(你的参数实例)
        fragmentB.show(supportFragmentManager, FragmentB.TAG)
    }
}

补充注意事项

  • 自定义参数类型如果不是基础类型,必须实现Parcelable接口才能存入Bundle。
  • 不要在Fragment的构造函数中添加任何参数,强制保留无参构造。

内容的提问来源于stack exchange,提问作者Anne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 14:15:03