();
sRFullMap.put(resType, fullMap);
for (Field f : inner.getDeclaredFields()) {
// only process static final fields. Since the final attribute may have
// been altered by layoutlib_create, we only check static
int modifiers = f.getModifiers();
if (Modifier.isStatic(modifiers)) {
Class> type = f.getType();
if (type.isArray() && type.getComponentType() == int.class) {
// if the object is an int[] we put it in sRArrayMap
sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
} else if (type == int.class) {
Integer value = (Integer) f.get(null);
sRMap.put(value, new String[] { f.getName(), resType });
fullMap.put(f.getName(), value);
} else {
assert false;
}
}
}
}
} catch (IllegalArgumentException e) {
// FIXME: log/return the error (there's no logger object at this point!)
e.printStackTrace();
return false;
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
}
return true;
}
@Override
public boolean dispose() {
BridgeAssetManager.clearSystem();
return true;
}
/**
* Starts a layout session by inflating and rendering it. The method returns a
* {@link ILayoutScene} on which further actions can be taken.
*
* @param layoutDescription the {@link IXmlPullParser} letting the LayoutLib Bridge visit the
* layout file.
* @param projectKey An Object identifying the project. This is used for the cache mechanism.
* @param screenWidth the screen width
* @param screenHeight the screen height
* @param renderFullSize if true, the rendering will render the full size needed by the
* layout. This size is never smaller than screenWidth x screenHeight.
* @param density the density factor for the screen.
* @param xdpi the screen actual dpi in X
* @param ydpi the screen actual dpi in Y
* @param themeName The name of the theme to use.
* @param isProjectTheme true if the theme is a project theme, false if it is a framework theme.
* @param projectResources the resources of the project. The map contains (String, map) pairs
* where the string is the type of the resource reference used in the layout file, and the
* map contains (String, {@link IResourceValue}) pairs where the key is the resource name,
* and the value is the resource value.
* @param frameworkResources the framework resources. The map contains (String, map) pairs
* where the string is the type of the resource reference used in the layout file, and the map
* contains (String, {@link IResourceValue}) pairs where the key is the resource name, and the
* value is the resource value.
* @param projectCallback The {@link IProjectCallback} object to get information from
* the project.
* @param logger the object responsible for displaying warning/errors to the user.
* @return a new {@link ILayoutScene} object that contains the result of the layout.
* @since 5
*/
@Override
public BridgeLayoutScene createScene(SceneParams params) {
try {
SceneResult lastResult = SceneStatus.SUCCESS.getResult();
LayoutSceneImpl scene = new LayoutSceneImpl(params);
try {
prepareThread();
lastResult = scene.init(params.getTimeout());
if (lastResult.isSuccess()) {
lastResult = scene.inflate();
if (lastResult.isSuccess()) {
lastResult = scene.render();
}
}
} finally {
scene.release();
cleanupThread();
}
return new BridgeLayoutScene(scene, lastResult);
} catch (Throwable t) {
// get the real cause of the exception.
Throwable t2 = t;
while (t2.getCause() != null) {
t2 = t.getCause();
}
return new BridgeLayoutScene(null,
SceneStatus.ERROR_UNKNOWN.getResult(t2.getMessage(), t2));
}
}
/*
* (non-Javadoc)
* @see com.android.layoutlib.api.ILayoutLibBridge#clearCaches(java.lang.Object)
*/
@Override
public void clearCaches(Object projectKey) {
if (projectKey != null) {
sProjectBitmapCache.remove(projectKey);
sProject9PatchCache.remove(projectKey);
}
}
/**
* Returns the lock for the bridge
*/
public static ReentrantLock getLock() {
return sLock;
}
/**
* Prepares the current thread for rendering.
*
* Note that while this can be called several time, the first call to {@link #cleanupThread()}
* will do the clean-up, and make the thread unable to do further scene actions.
*/
public static void prepareThread() {
// we need to make sure the Looper has been initialized for this thread.
// this is required for View that creates Handler objects.
if (Looper.myLooper() == null) {
Looper.prepare();
}
}
/**
* Cleans up thread-specific data. After this, the thread cannot be used for scene actions.
*
* Note that it doesn't matter how many times {@link #prepareThread()} was called, a single
* call to this will prevent the thread from doing further scene actions
*/
public static void cleanupThread() {
// clean up the looper
Looper.sThreadLocal.remove();
}
/**
* Returns details of a framework resource from its integer value.
* @param value the integer value
* @return an array of 2 strings containing the resource name and type, or null if the id
* does not match any resource.
*/
public static String[] resolveResourceValue(int value) {
return sRMap.get(value);
}
/**
* Returns the name of a framework resource whose value is an int array.
* @param array
*/
public static String resolveResourceValue(int[] array) {
sIntArrayWrapper.set(array);
return sRArrayMap.get(sIntArrayWrapper);
}
/**
* Returns the integer id of a framework resource, from a given resource type and resource name.
* @param type the type of the resource
* @param name the name of the resource.
* @return an {@link Integer} containing the resource id, or null if no resource were found.
*/
public static Integer getResourceValue(String type, String name) {
Map map = sRFullMap.get(type);
if (map != null) {
return map.get(name);
}
return null;
}
/**
* Returns the list of possible enums for a given attribute name.
*/
public static Map getEnumValues(String attributeName) {
if (sEnumValueMap != null) {
return sEnumValueMap.get(attributeName);
}
return null;
}
/**
* Returns the bitmap for a specific path, from a specific project cache, or from the
* framework cache.
* @param value the path of the bitmap
* @param projectKey the key of the project, or null to query the framework cache.
* @return the cached Bitmap or null if not found.
*/
public static Bitmap getCachedBitmap(String value, Object projectKey) {
if (projectKey != null) {
Map> map = sProjectBitmapCache.get(projectKey);
if (map != null) {
SoftReference ref = map.get(value);
if (ref != null) {
return ref.get();
}
}
} else {
SoftReference ref = sFrameworkBitmapCache.get(value);
if (ref != null) {
return ref.get();
}
}
return null;
}
/**
* Sets a bitmap in a project cache or in the framework cache.
* @param value the path of the bitmap
* @param bmp the Bitmap object
* @param projectKey the key of the project, or null to put the bitmap in the framework cache.
*/
public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
if (projectKey != null) {
Map> map = sProjectBitmapCache.get(projectKey);
if (map == null) {
map = new HashMap>();
sProjectBitmapCache.put(projectKey, map);
}
map.put(value, new SoftReference(bmp));
} else {
sFrameworkBitmapCache.put(value, new SoftReference(bmp));
}
}
/**
* Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
* framework cache.
* @param value the path of the 9 patch
* @param projectKey the key of the project, or null to query the framework cache.
* @return the cached 9 patch or null if not found.
*/
public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
if (projectKey != null) {
Map> map = sProject9PatchCache.get(projectKey);
if (map != null) {
SoftReference ref = map.get(value);
if (ref != null) {
return ref.get();
}
}
} else {
SoftReference ref = sFramework9PatchCache.get(value);
if (ref != null) {
return ref.get();
}
}
return null;
}
/**
* Sets a 9 patch chunk in a project cache or in the framework cache.
* @param value the path of the 9 patch
* @param ninePatch the 9 patch object
* @param projectKey the key of the project, or null to put the bitmap in the framework cache.
*/
public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
if (projectKey != null) {
Map> map = sProject9PatchCache.get(projectKey);
if (map == null) {
map = new HashMap>();
sProject9PatchCache.put(projectKey, map);
}
map.put(value, new SoftReference(ninePatch));
} else {
sFramework9PatchCache.put(value, new SoftReference(ninePatch));
}
}
}