private ResourceValue resolveResValue(ResourceValue resValue, int depth) { if (resValue == null) { return null; } // if the resource value is null, we simply return it. String value = resValue.getValue(); if (value == null) { return resValue; } // else attempt to find another ResourceValue referenced by this one. ResourceValue resolvedResValue = findResValue(value, resValue.isFramework()); // if the value did not reference anything, then we simply return the input value if (resolvedResValue == null) { return resValue; } // detect potential loop due to mishandled namespace in attributes if (resValue == resolvedResValue || depth >= MAX_RESOURCE_INDIRECTION) { if (mLogger != null) { mLogger.error( LayoutLog.TAG_BROKEN, String.format( "Potential stack overflow trying to resolve '%s': cyclic resource definitions? Render may not be accurate.", value), null); } return resValue; } // otherwise, we attempt to resolve this new value as well return resolveResValue(resolvedResValue, depth + 1); }
@Override public ResourceValue findResValue(String reference, boolean forceFrameworkOnly) { if (!mLookupChain.isEmpty() && reference.startsWith(PREFIX_RESOURCE_REF)) { ResourceValue prev = mLookupChain.get(mLookupChain.size() - 1); if (!reference.equals(prev.getValue())) { ResourceValue next = new ResourceValue(prev.getResourceType(), prev.getName(), prev.isFramework()); next.setValue(reference); mLookupChain.add(next); } } ResourceValue resValue = super.findResValue(reference, forceFrameworkOnly); if (resValue != null) { mLookupChain.add(resValue); } return resValue; }