一、在Fragment中getActivity()和getContext()为空

Fragment onDetach() 方法执行后,在调用 getActitity() 方法,返回的就是 NULL

  • Fragment 类中搜索 getActivity() getContext() 方法,根据解决方案修改;
  • Fragment 中维护 Activity 成员变量,代替 getActivity() getContext() 的调用;
  • getActivity() 必须赋值给一个变量,不能无效判空,例如:
  • if (getActivity() != null) {
        getActivity().getResource();
    
    二、在Fragment中getResources()触发not attached to Activity异常

    在Fragment中执行异步任务,如果这时候如果Activity触发了重建,那么在异步任务中调用getResources()就会触发not attached to Activity异常,其内部也是调用requireContext()方法

  • 搜索在Fragment异步任务中调用getResources()的地方;
  • 在调用getResources()之前调用isAdded()方法,判断当前Fragment是否添加到了Activity中;
  • 使用getContext()方法先判断Context是否为NULL
  • 三、在Fragment中使用requireContext()方法,触发not attached to Activity异常

    requireContext方法如下,在Fragment没有Attach到Activity时,调用该方法会触发异常;

     * Return the {@link Context} this fragment is currently associated with.  * @throws IllegalStateException if not currently associated with a context.  * @see #getContext() @NonNull public final Context requireContext() {    Context context = getContext();    if (context == null) {        throw new IllegalStateException("Fragment " + this + " not attached to a context.");    return context;
  • 在Fragemnt方法中搜索requireContext()方法;
  • 捕获异常IllegalStateException
  • 使用getContext()方法先判断Context是否为NULL
  • 四、Fragment重建找不到默认构造方法和参数丢失

    每一个Fragment必须要有默认的构造函数,使用setArguments方法保存参数。

    Constructor used by the default FragmentFactory. You must set a custom FragmentFactory if you want to use a non-default constructor to ensure that your constructor is called when the fragment is re-instantiated.

    It is strongly recommended to supply arguments with setArguments(Bundle) and later retrieved by the Fragment with getArguments(). These arguments are automatically saved and restored alongside the Fragment.

    Activity恢复时,会使用默认构造方法重建Fragment,如果没有默认构造函数的话,就会报java.lang.InstantiationException异常

  • Fragment类如果自定义了构造方法,必须定义一个默认构造函数;
  • Fragment必须使用setArguments方法保存参数;
  • 使用newInstance静态方法
  • public static FilterPanelFragment newInstance(boolean isAsset) {
        Bundle args = new Bundle();
        args.putBoolean("isAsset", isAsset);
        FilterPanelFragment fragment = new FilterPanelFragment();
        fragment.setArguments(args);
        return fragment;
    复制代码
    分类:
    Android
    标签: