很多人平时已经写过许多Fragment的代码,觉得自己对Fragment已经很熟悉。但是其实对于很多人来说,Fragment并不像自己想象的那么熟悉。
很多时候使用Fragment总是会莫名其妙出现空指针问题。下面就来说说很多人不太熟悉的地方。
我们初始化Fragment的时候经常会习惯性的 new Fragment(参数...); 但是,当我们扒开android的源码时,却发现不是那么回事。
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); 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); } }
你会发现Fagment初始化调用的是Fragment里面的静态方法,而且是通过反射的方式调用的。反射则意味着他只会调用无参构造函数。
你会发现传参数用的方法是setArguments(Bundle)