LayoutLib: Fix typedArray caching.

The typedArray depends on the current context (more specifically, the
themes set on the context). The fact was ignored in the caching of the
typedArray and caused the android:theme attribute to be ignored in
certain cases.

Change-Id: If095580919474f12c0eb4e1f8fb7f076cf3c4ed0
This commit is contained in:
Deepanshu Gupta
2015-08-26 11:54:50 -07:00
parent 199c74eab1
commit eb26f5cecd

View File

@@ -36,8 +36,8 @@ import com.android.util.Pair;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import android.annotation.Nullable;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.ContentResolver; import android.content.ContentResolver;
@@ -136,8 +136,9 @@ public final class BridgeContext extends Context {
private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap; private Map<StyleResourceValue, Integer> mStyleToDynamicIdMap;
private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
// cache for TypedArray generated from IStyleResourceValue object // cache for TypedArray generated from StyleResourceValue object
private Map<int[], Map<Integer, BridgeTypedArray>> mTypedArrayCache; private Map<int[], Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>
mTypedArrayCache;
private BridgeInflater mBridgeInflater; private BridgeInflater mBridgeInflater;
private BridgeContentResolver mContentResolver; private BridgeContentResolver mContentResolver;
@@ -588,31 +589,38 @@ public final class BridgeContext extends Context {
} }
} }
// The map is from
// attrs (int[]) -> context's current themes (List<StyleRV>) -> resid (int) -> typed array.
if (mTypedArrayCache == null) { if (mTypedArrayCache == null) {
mTypedArrayCache = new HashMap<int[], Map<Integer,BridgeTypedArray>>(); mTypedArrayCache = new IdentityHashMap<int[],
Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>();
Map<Integer, BridgeTypedArray> map = new HashMap<Integer, BridgeTypedArray>();
mTypedArrayCache.put(attrs, map);
BridgeTypedArray ta = createStyleBasedTypedArray(style, attrs);
map.put(resid, ta);
return ta;
} }
// get the 2nd map // get the 2nd map
Map<Integer, BridgeTypedArray> map = mTypedArrayCache.get(attrs); Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>> map2 =
if (map == null) { mTypedArrayCache.get(attrs);
map = new HashMap<Integer, BridgeTypedArray>(); if (map2 == null) {
mTypedArrayCache.put(attrs, map); map2 = new HashMap<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>();
mTypedArrayCache.put(attrs, map2);
} }
// get the array from the 2nd map // get the 3rd map
BridgeTypedArray ta = map.get(resid); List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
Map<Integer, BridgeTypedArray> map3 = map2.get(currentThemes);
if (map3 == null) {
map3 = new HashMap<Integer, BridgeTypedArray>();
// Create a copy of the list before adding it to the map. This allows reusing the
// existing list.
currentThemes = new ArrayList<StyleResourceValue>(currentThemes);
map2.put(currentThemes, map3);
}
// get the array from the 3rd map
BridgeTypedArray ta = map3.get(resid);
if (ta == null) { if (ta == null) {
ta = createStyleBasedTypedArray(style, attrs); ta = createStyleBasedTypedArray(style, attrs);
map.put(resid, ta); map3.put(resid, ta);
} }
return ta; return ta;