Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fatal Exception: java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager. #31

Open
kakarrot opened this issue Jun 25, 2021 · 13 comments
Labels
bug Something isn't working

Comments

@kakarrot
Copy link

Fatal Exception: java.lang.IllegalStateException
onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.

androidx.fragment.app.Fragment.getLayoutInflater (Fragment.java:1673)
androidx.fragment.app.Fragment.getLayoutInflater (Fragment.java:1639)
com.hi.dhl.binding.databind.FragmentDataBinding.getValue (FragmentDataBinding.java:35)

报错 FragmentDataBinding 行数: 35,但使用的Fragment(layoutId: Int) 构造方法,

按常理:在onViewCreated() 方法后调用,

FragmentDataBinding 中第 35 行
thisRef.view == null 应该为 false,除非什么异常情况导致执行此句,

然后,想到可能和fragment 的恢复有关系,恢复的时候 走的是 Fragment() 无参数方法,layoutId = 0, 所以 view 为空

目前尝试在 onSaveInstance() 里面保存 layoutId,在恢复时重新将 layoutId 还原

所以也不全是这个库的问题,只是报错的地方在库里面而已

@hi-dhl
Copy link
Owner

hi-dhl commented Jun 25, 2021

收到,感谢反馈,我这里尝试复现一下

@hi-dhl
Copy link
Owner

hi-dhl commented Jun 26, 2021

请修改一下使用方式,不用在构造函数中传递 layoutId,使用如下方式

class FragmentNav1 : Fragment() {
    
    // DataBinding
  	val binding: FragmentMainBinding by databind()
    
    // ViewBinding
  	 val binding: FragmentMainBinding by viewbind()
  
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return binding.root
    }
}

@kakarrot
Copy link
Author

kakarrot commented Jul 2, 2021

请修改一下使用方式,不用在构造函数中传递 layoutId,使用如下方式

class FragmentNav1 : Fragment() {
    
    // DataBinding
  	val binding: FragmentMainBinding by databind()
    
    // ViewBinding
  	 val binding: FragmentMainBinding by viewbind()
  
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return binding.root
    }
}

试了一下,使用此方式bug依然存在,找了一下,发现这个链接:

https://blog.csdn.net/yechaoa/article/details/81017600

可能跟在Fragment中使用有关系,建议兼容一下

另外,这篇文章:
https://itnext.io/an-update-to-the-fragmentviewbindingdelegate-the-bug-weve-inherited-from-autoclearedvalue-7fc0a89fcae1

有更新,建议同步更新一下FragmentDelegate<T: ViewBinding> 实现

@hi-dhl
Copy link
Owner

hi-dhl commented Jul 2, 2021

@kakarrot 收到,感谢提供的方案,我研究一下,我会尽快更新版本

@hi-dhl hi-dhl added the bug Something isn't working label Jul 4, 2021
@hi-dhl
Copy link
Owner

hi-dhl commented Jul 4, 2021

请修改一下使用方式,不用在构造函数中传递 layoutId,使用如下方式

class FragmentNav1 : Fragment() {
    
    // DataBinding
  	val binding: FragmentMainBinding by databind()
    
    // ViewBinding
  	 val binding: FragmentMainBinding by viewbind()
  
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return binding.root
    }
}

试了一下,使用此方式bug依然存在,找了一下,发现这个链接:

https://blog.csdn.net/yechaoa/article/details/81017600

可能跟在Fragment中使用有关系,建议兼容一下

另外,这篇文章:
https://itnext.io/an-update-to-the-fragmentviewbindingdelegate-the-bug-weve-inherited-from-autoclearedvalue-7fc0a89fcae1

有更新,建议同步更新一下FragmentDelegate<T: ViewBinding> 实现

想请问一下你的 Fragment 的版本号是多少?我这边尝试了以上文章的两种方式,均可以正常运行,可否留一个微信,想咨询一下步骤

@kakarrot
Copy link
Author

kakarrot commented Jul 5, 2021

androidx.fragment:fragment-ktx:1.3.1

嵌套的3层fragment,最里层的fragment被动态添加/显示/隐藏,bug不是必现的,自己手机没有发生过,目前看到的都是

Firebase统计上报过来的记录,也没有固定的手机型号和Android版本,应该是在特殊情况下才能复现。

@hy-liuyuzhe
Copy link

hy-liuyuzhe commented Apr 8, 2022

我也遇到了,最后发现是网络请求回调时,界面已经销毁了,但你还使用databing对象就会必现。

@hi-dhl
Copy link
Owner

hi-dhl commented Apr 8, 2022

我也遇到了,最后发现是网络请求回调时,界面已经销毁了,但你还使用databing对象就会必现。

页面销毁的时候, binding 实例也会跟着销毁

@kakarrot
Copy link
Author

fragment 在 onDestroyView() 里面如果调用 binding 停止动画,释放资源的时候,binding已经为空了,所以最好的binding置null 时机应该是 onDestoryView() 执行结束后,我使用的时候改成了下面的实现

com/hi/dhl/binding/base/FragmentDelegate.kt

@hi-dhl
Copy link
Owner

hi-dhl commented Apr 26, 2022

fragment 在 onDestroyView() 里面如果调用 binding 停止动画,释放资源的时候,binding已经为空了,所以最好的binding置null 时机应该是 onDestoryView() 执行结束后,我使用的时候改成了下面的实现

com/hi/dhl/binding/base/FragmentDelegate.kt

感谢反馈,你是对的,我看了一下,确实应该在 Fragment#onDestoryView 之后进行销毁。

@hi-dhl
Copy link
Owner

hi-dhl commented Apr 26, 2022

我也遇到了,最后发现是网络请求回调时,界面已经销毁了,但你还使用databing对象就会必现。

@hy-liuyuzhe 销毁之后,如果再次使用,由于 delegate property 会被再次初始化。 这应该也是 @kakarrot 反馈的这个问题#31 (comment) 的原因,我会尽快修复这个问题

@jqorz
Copy link

jqorz commented Mar 2, 2023

Fragment中如果在lifecycleScope.launchWithCatch的onFinally回调里使用bind对象并且此时界面销毁了,还是会报错 java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager. v1.1.9

@hi-dhl
Copy link
Owner

hi-dhl commented Mar 3, 2023

Fragment中如果在lifecycleScope.launchWithCatch的onFinally回调里使用bind对象并且此时界面销毁了,还是会报错 java.lang.IllegalStateException: onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager. v1.1.9

你好,可否添加我的wechat : hi-dhl, 想详细咨询一下

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants