Android碎片例項化方法:instantiate的使用及其原始碼解析
阿新 • • 發佈:2019-01-21
正常是通過呼叫碎片的空的構造方法來例項化一個碎片物件,但是這不利於同時管理一批碎片的情況,因為開閉原則的需要,正常的例項方法根本滿足不了。
這裡用的是instantiate
使用方法,通過傳入不同的碎片類名例項化。
Fragment fragment = Fragment.instantiate(mContext, newNav.getClx().getName(), null);
引數
1.上下文
2.碎片的類名,和碎片的例項一同被維護在某個類中
3.Bundle 你可以理解為arguments 就是你賦給碎片的標識 在導航欄中常見
原始碼
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.newInstance(); if (args != null) { args.setClassLoader(f.getClass().getClassLoader()); f.mArguments = 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); } }
首先碎片的例項化有一個快取機制。
private static final SimpleArrayMap<String, Class<?>> sClassMap = new SimpleArrayMap<String, Class<?>>();快取的是什麼呢?快取的是碎片的類。如果你之前例項化過這個碎片了,你的類就會被存到這個map中去,然後下一次你就不需要通過類名來找到這個類了。
下面的程式碼就是快取過程,就是以空間換取時間
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); }而
clazz = context.getClassLoader().loadClass(fname);
這句話就是通過類名來取得類的方法。這就是一種反射機制,通過類名來取得類,再由類來例項化。
例項化
Fragment f = (Fragment)clazz.newInstance();
最後你的碎片標識
if (args != null) { args.setClassLoader(f.getClass().getClassLoader()); f.mArguments = args; }