1. 程式人生 > >Android碎片例項化方法:instantiate的使用及其原始碼解析

Android碎片例項化方法:instantiate的使用及其原始碼解析

正常是通過呼叫碎片的空的構造方法來例項化一個碎片物件,但是這不利於同時管理一批碎片的情況,因為開閉原則的需要,正常的例項方法根本滿足不了。

這裡用的是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;
}