FileDocCategorySizeDatePackage
Bridge.javaAPI DocAndroid 5.1 API22860Thu Mar 12 22:22:44 GMT 2015com.android.layoutlib.bridge

Bridge

public final class Bridge extends com.android.ide.common.rendering.api.Bridge
Main entry point of the LayoutLib Bridge.

To use this bridge, simply instantiate an object of type {@link Bridge} and call {@link #createSession(SessionParams)}

Fields Summary
private static final String
ICU_LOCALE_DIRECTION_RTL
private static final ReentrantLock
sLock
Lock to ensure only one rendering/inflating happens at a time. This is due to some singleton in the Android framework.
private static final Map
sRMap
Maps from id to resource type/name. This is for com.android.internal.R
private static final Map
sRArrayMap
Same as sRMap except for int[] instead of int resources. This is for android.R only.
private static final Map
sRevRMap
Reverse map compared to sRMap, resource type -> (resource name -> id). This is for com.android.internal.R.
private static final int
DYNAMIC_ID_SEED_START
private static final com.android.layoutlib.bridge.util.DynamicIdMap
sDynamicIds
private static final Map
sProjectBitmapCache
private static final Map
sProject9PatchCache
private static final Map
sFrameworkBitmapCache
private static final Map
sFramework9PatchCache
private static Map
sEnumValueMap
private static Map
sPlatformProperties
private static final IntArray
sIntArrayWrapper
Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}.
private static final com.android.ide.common.rendering.api.LayoutLog
sDefaultLog
A default log than prints to stdout/stderr.
private static com.android.ide.common.rendering.api.LayoutLog
sCurrentLog
Current log.
private static final int
LAST_SUPPORTED_FEATURE
Constructors Summary
Methods Summary
public static voidcleanupThread()
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

        // clean up the looper
        Looper_Accessor.cleanupThread();
    
public voidclearCaches(java.lang.Object projectKey)

        if (projectKey != null) {
            sProjectBitmapCache.remove(projectKey);
            sProject9PatchCache.remove(projectKey);
        }
    
public com.android.ide.common.rendering.api.RenderSessioncreateSession(com.android.ide.common.rendering.api.SessionParams params)
Starts a layout session by inflating and rendering it. The method returns a {@link RenderSession} on which further actions can be taken.

param
params the {@link SessionParams} object with all the information necessary to create the scene.
return
a new {@link RenderSession} object that contains the result of the layout.
since
5

        try {
            Result lastResult = SUCCESS.createResult();
            RenderSessionImpl scene = new RenderSessionImpl(params);
            try {
                prepareThread();
                lastResult = scene.init(params.getTimeout());
                if (lastResult.isSuccess()) {
                    lastResult = scene.inflate();
                    if (lastResult.isSuccess()) {
                        lastResult = scene.render(true /*freshRender*/);
                    }
                }
            } finally {
                scene.release();
                cleanupThread();
            }

            return new BridgeRenderSession(scene, lastResult);
        } catch (Throwable t) {
            // get the real cause of the exception.
            Throwable t2 = t;
            while (t2.getCause() != null) {
                t2 = t.getCause();
            }
            return new BridgeRenderSession(null,
                    ERROR_UNKNOWN.createResult(t2.getMessage(), t));
        }
    
public booleandispose()

        BridgeAssetManager.clearSystem();

        // dispose of the default typeface.
        Typeface_Delegate.resetDefaults();

        return true;
    
public intgetApiLevel()


    
       
        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
    
public static com.android.ninepatch.NinePatchChunkgetCached9Patch(java.lang.String value, java.lang.Object projectKey)
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.

        if (projectKey != null) {
            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);

            if (map != null) {
                SoftReference<NinePatchChunk> ref = map.get(value);
                if (ref != null) {
                    return ref.get();
                }
            }
        } else {
            SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
            if (ref != null) {
                return ref.get();
            }
        }

        return null;
    
public static android.graphics.BitmapgetCachedBitmap(java.lang.String value, java.lang.Object projectKey)
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.

        if (projectKey != null) {
            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
            if (map != null) {
                SoftReference<Bitmap> ref = map.get(value);
                if (ref != null) {
                    return ref.get();
                }
            }
        } else {
            SoftReference<Bitmap> ref = sFrameworkBitmapCache.get(value);
            if (ref != null) {
                return ref.get();
            }
        }

        return null;
    
public java.util.EnumSetgetCapabilities()

        // The Capability class is deprecated and frozen. All Capabilities enumerated there are
        // supported by this version of LayoutLibrary. So, it's safe to use EnumSet.allOf()
        return EnumSet.allOf(Capability.class);
    
public static java.util.MapgetEnumValues(java.lang.String attributeName)
Returns the list of possible enums for a given attribute name.

        if (sEnumValueMap != null) {
            return sEnumValueMap.get(attributeName);
        }

        return null;
    
public static java.util.concurrent.locks.ReentrantLockgetLock()
Returns the lock for the bridge

        return sLock;
    
public static com.android.ide.common.rendering.api.LayoutLoggetLog()

        return sCurrentLog;
    
public static java.util.MapgetPlatformProperties()
Returns the platform build properties.

        return sPlatformProperties;
    
public static java.lang.IntegergetResourceId(com.android.resources.ResourceType type, java.lang.String name)
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.

        Map<String, Integer> map = sRevRMap.get(type);
        Integer value = null;
        if (map != null) {
            value = map.get(name);
        }

        return value == null ? sDynamicIds.getId(type, name) : value;

    
public com.android.ide.common.rendering.api.ResultgetViewIndex(java.lang.Object viewObject)

        if (viewObject instanceof View) {
            View view = (View) viewObject;
            ViewParent parentView = view.getParent();

            if (parentView instanceof ViewGroup) {
                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
            }

            return Status.SUCCESS.createResult();
        }

        throw new IllegalArgumentException("viewObject is not a View");
    
public com.android.ide.common.rendering.api.ResultgetViewParent(java.lang.Object viewObject)

        if (viewObject instanceof View) {
            return Status.SUCCESS.createResult(((View)viewObject).getParent());
        }

        throw new IllegalArgumentException("viewObject is not a View");
    
public booleaninit(java.util.Map platformProperties, java.io.File fontLocation, java.util.Map enumValueMap, com.android.ide.common.rendering.api.LayoutLog log)

        sPlatformProperties = platformProperties;
        sEnumValueMap = enumValueMap;

        BridgeAssetManager.initSystem();

        // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
        // on static (native) methods which prints the signature on the console and
        // throws an exception.
        // This is useful when testing the rendering in ADT to identify static native
        // methods that are ignored -- layoutlib_create makes them returns 0/false/null
        // which is generally OK yet might be a problem, so this is how you'd find out.
        //
        // Currently layoutlib_create only overrides static native method.
        // Static non-natives are not overridden and thus do not get here.
        final String debug = System.getenv("DEBUG_LAYOUT");
        if (debug != null && !debug.equals("0") && !debug.equals("false")) {

            OverrideMethod.setDefaultListener(new MethodAdapter() {
                @Override
                public void onInvokeV(String signature, boolean isNative, Object caller) {
                    sDefaultLog.error(null, "Missing Stub: " + signature +
                            (isNative ? " (native)" : ""), null /*data*/);

                    if (debug.equalsIgnoreCase("throw")) {
                        // Throwing this exception doesn't seem that useful. It breaks
                        // the layout editor yet doesn't display anything meaningful to the
                        // user. Having the error in the console is just as useful. We'll
                        // throw it only if the environment variable is "throw" or "THROW".
                        throw new StaticMethodNotImplementedException(signature);
                    }
                }
            });
        }

        // load the fonts.
        FontFamily_Delegate.setFontLocation(fontLocation.getAbsolutePath());
        MemoryMappedFile_Delegate.setDataDir(fontLocation.getAbsoluteFile().getParentFile());

        // now parse com.android.internal.R (and only this one as android.R is a subset of
        // the internal version), and put the content in the maps.
        try {
            Class<?> r = com.android.internal.R.class;

            for (Class<?> inner : r.getDeclaredClasses()) {
                String resTypeName = inner.getSimpleName();
                ResourceType resType = ResourceType.getEnum(resTypeName);
                if (resType != null) {
                    Map<String, Integer> fullMap = new HashMap<String, Integer>();
                    sRevRMap.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 using an IntArray
                                // wrapper that properly implements equals and hashcode for the array
                                // objects, as required by the map contract.
                                sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
                            } else if (type == int.class) {
                                Integer value = (Integer) f.get(null);
                                sRMap.put(value, Pair.of(resType, f.getName()));
                                fullMap.put(f.getName(), value);
                            } else {
                                assert false;
                            }
                        }
                    }
                }
            }
        } catch (Throwable throwable) {
            if (log != null) {
                log.error(LayoutLog.TAG_BROKEN,
                        "Failed to load com.android.internal.R from the layout library jar",
                        throwable, null);
            }
            return false;
        }

        return true;
    
public static booleanisLocaleRtl(java.lang.String locale)

        if (locale == null) {
            locale = "";
        }
        ULocale uLocale = new ULocale(locale);
        return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL);
    
public booleanisRtl(java.lang.String locale)

        return isLocaleRtl(locale);
    
public static voidprepareThread()
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.

        // 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.prepareMainLooper();
        }
    
public com.android.ide.common.rendering.api.ResultrenderDrawable(com.android.ide.common.rendering.api.DrawableParams params)

        try {
            Result lastResult = SUCCESS.createResult();
            RenderDrawable action = new RenderDrawable(params);
            try {
                prepareThread();
                lastResult = action.init(params.getTimeout());
                if (lastResult.isSuccess()) {
                    lastResult = action.render();
                }
            } finally {
                action.release();
                cleanupThread();
            }

            return lastResult;
        } catch (Throwable t) {
            // get the real cause of the exception.
            Throwable t2 = t;
            while (t2.getCause() != null) {
                t2 = t.getCause();
            }
            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
        }
    
public static com.android.util.PairresolveResourceId(int value)
Returns details of a framework resource from its integer value.

param
value the integer value
return
a Pair containing the resource type and name, or null if the id does not match any resource.

        Pair<ResourceType, String> pair = sRMap.get(value);
        if (pair == null) {
            pair = sDynamicIds.resolveId(value);
            if (pair == null) {
                //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
            }
        }
        return pair;
    
public static java.lang.StringresolveResourceId(int[] array)
Returns the name of a framework resource whose value is an int array.

        sIntArrayWrapper.set(array);
        return sRArrayMap.get(sIntArrayWrapper);
    
public static voidsetCached9Patch(java.lang.String value, com.android.ninepatch.NinePatchChunk ninePatch, java.lang.Object projectKey)
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.

        if (projectKey != null) {
            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);

            if (map == null) {
                map = new HashMap<String, SoftReference<NinePatchChunk>>();
                sProject9PatchCache.put(projectKey, map);
            }

            map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
        } else {
            sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
        }
    
public static voidsetCachedBitmap(java.lang.String value, android.graphics.Bitmap bmp, java.lang.Object projectKey)
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.

        if (projectKey != null) {
            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);

            if (map == null) {
                map = new HashMap<String, SoftReference<Bitmap>>();
                sProjectBitmapCache.put(projectKey, map);
            }

            map.put(value, new SoftReference<Bitmap>(bmp));
        } else {
            sFrameworkBitmapCache.put(value, new SoftReference<Bitmap>(bmp));
        }
    
public static voidsetLog(com.android.ide.common.rendering.api.LayoutLog log)

        // check only the thread currently owning the lock can do this.
        if (!sLock.isHeldByCurrentThread()) {
            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
        }

        if (log != null) {
            sCurrentLog = log;
        } else {
            sCurrentLog = sDefaultLog;
        }
    
public booleansupports(int feature)

        return feature <= LAST_SUPPORTED_FEATURE;