Android bugs——Caused by: android.support.v4.app.Fragment$InstantiationException

Error:

Caused by: android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment xxx: make sure class name exists, is public, and has an empty constructor that is public

原因:

当切换到其他应用时,会调用FragmentActivity的onSaveInstanceState方法,再次进入,Activity会重新创建,onCreate方法中会拿到savedInstanceState并re-instantiate。具体参考下源码:

public static Fragment instantiate(Context context, String fname, @Nullable Bundle args) {
        try {
            Class<?> clazz = sClassMap.get(fname);
            if (clazz == null) {
                // Class not found in the cache, see if it's real, and try to add it
                clazz = context.getClassLoader().loadClass(fname);
                if (!Fragment.class.isAssignableFrom(clazz)) {
                    throw new InstantiationException("Trying to instantiate a class " + fname
                            + " that is not a Fragment", new ClassCastException());
                }
                sClassMap.put(fname, clazz);
            }
            Fragment f = (Fragment) clazz.getConstructor().newInstance();
            if (args != null) {
                args.setClassLoader(f.getClass().getClassLoader());
                f.setArguments(args);
            }
            return f;
        } catch (ClassNotFoundException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": make sure class name exists, is public, and has an"
                    + " empty constructor that is public", e);
        } catch (java.lang.InstantiationException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": make sure class name exists, is public, and has an"
                    + " empty constructor that is public", e);
        } catch (IllegalAccessException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": make sure class name exists, is public, and has an"
                    + " empty constructor that is public", e);
        } catch (NoSuchMethodException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": could not find Fragment constructor", e);
        } catch (InvocationTargetException e) {
            throw new InstantiationException("Unable to instantiate fragment " + fname
                    + ": calling Fragment constructor caused an exception", e);
        }
    }

Fragment f = (Fragment) clazz.getConstructor().newInstance();
看到这行代码原因已经非常明显了,重新构建Fragment时,反射调用了Fragment的无参构造方法,找不到无参构造方法就创建失败了。

解决方法:

给只有有参构造方法的Fragment添加一个无参构造方法。

猜你喜欢

转载自blog.csdn.net/u012230055/article/details/124560514