Kotlin中是否可以像使用Activity一样使用Fragment?
能否完全参照Activity的写法编写Fragment代码?
结论:不能,强行照搬Activity的编码逻辑会大概率触发空指针、内存泄漏、功能失效甚至崩溃问题。
两者核心逻辑差异很大,照搬最容易踩的坑包括:
- 生命周期逻辑不匹配
Activity的实例生命周期和自身视图生命周期完全绑定,在onCreate里做控件初始化、视图操作完全没问题。但Fragment存在两套独立生命周期:Fragment实例的生命周期、其托管视图的生命周期。如果照搬Activity写法在onCreate阶段操作控件,会直接触发空指针;如果把资源释放逻辑全写到onDestroy里,会因为Fragment进入返回栈时视图已经销毁、但实例未销毁,导致视图引用长期持有引发内存泄漏。 - Context获取逻辑不一致
Activity本身是Context子类,全局任意位置用this即可获取有效上下文。但Fragment的Context来自其附着的宿主Activity,只有在onAttach到onDetach区间内才能获取到有效Context,照搬Activity的写法在类初始化、onCreate之前随意调用Context,会出现空指针、资源ID匹配错误、弹窗依附错误窗口的问题。另外Fragment无法直接调用setResult、直接拦截物理返回键,照搬Activity的返回逻辑会直接失效。 - 视图持有规则不同
Activity的视图和实例同生共死,只要实例没销毁,视图引用就一直有效。但Fragment在被替换、加入返回栈时,视图会先行销毁、实例保留,如果照着Activity的习惯长期持有ViewBinding、控件引用、列表适配器,会出现视图泄漏、View already has a parent崩溃、回到Fragment时显示旧视图的问题。 - 实例重建规则不同
Activity可以通过自定义构造函数传参,Intent传参也没有强限制。但Fragment在系统配置变更(如转屏、内存不足回收后重建)时,会强制调用无参构造函数生成新实例,如果照搬Activity的写法写有参构造传参,重建时会直接崩溃,必须通过argumentsBundle传递初始化参数。
编写Fragment时不需要完全和Activity做切割,业务逻辑、数据请求这类和视图、宿主无关的代码逻辑可以复用Activity的写法,但涉及生命周期、视图操作、上下文获取、参数传递的部分,必须严格遵循Fragment自身的规则:所有视图操作严格限制在
onViewCreated到onDestroyView区间,视图销毁时及时清空视图相关引用,依赖宿主的操作先判断Fragment是否处于附着状态。
内容的提问来源于stack exchange,提问作者alpheratz
相关产品推荐
相关产品推荐

