use libandroidfw for resource XML parsing

androidfw is implemented in native code and has much better performance
than ARSClib
This commit is contained in:
Julian Winkler
2024-05-12 17:03:27 +02:00
committed by Mis012
parent e2edbb0b59
commit cc5d4a3cb3
9 changed files with 280 additions and 115 deletions

View File

@@ -86,6 +86,7 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
'src/api-impl-jni/audio/android_media_SoundPool.c', 'src/api-impl-jni/audio/android_media_SoundPool.c',
'src/api-impl-jni/content/android_content_ClipboardManager.c', 'src/api-impl-jni/content/android_content_ClipboardManager.c',
'src/api-impl-jni/content/android_content_Context.c', 'src/api-impl-jni/content/android_content_Context.c',
'src/api-impl-jni/content/android_content_res_XmlBlock.c',
'src/api-impl-jni/database/android_database_SQLiteCommon.c', 'src/api-impl-jni/database/android_database_SQLiteCommon.c',
'src/api-impl-jni/database/android_database_SQLiteConnection.c', 'src/api-impl-jni/database/android_database_SQLiteConnection.c',
'src/api-impl-jni/egl/com_google_android_gles_jni_EGLImpl.c', 'src/api-impl-jni/egl/com_google_android_gles_jni_EGLImpl.c',

View File

@@ -447,3 +447,16 @@ JNIEXPORT jobjectArray JNICALL Java_android_content_res_AssetManager_list(JNIEnv
return array; return array;
} }
JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_openXmlAssetNative(JNIEnv *env, jobject this, jint cookie, jstring _file_name)
{
struct AssetManager *asset_manager = _PTR(_GET_LONG_FIELD(this, "mObject"));
const char *file_name = (*env)->GetStringUTFChars(env, _file_name, NULL);
struct Asset *asset = AssetManager_openNonAsset(asset_manager, file_name, ACCESS_BUFFER);
(*env)->ReleaseStringUTFChars(env, _file_name, file_name);
struct ResXMLTree *res_xml = ResXMLTree_new();
ResXMLTree_setTo(res_xml, Asset_getBuffer(asset, true), Asset_getLength(asset), true);
Asset_delete(asset);
return _INTPTR(res_xml);
}

View File

@@ -0,0 +1,127 @@
#include <androidfw/androidfw_c_api.h>
#include "../generated_headers/android_content_res_XmlBlock.h"
#include "../defines.h"
JNIEXPORT jlong JNICALL Java_android_content_res_XmlBlock_nativeCreateParseState(JNIEnv *env, jobject this, jlong block)
{
struct ResXMLTree *tree = (struct ResXMLTree *)_PTR(block);
struct ResXMLParser *parser = ResXMLParser_new(tree);
ResXMLParser_restart(parser);
return _INTPTR(parser);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeNext(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
enum event_code_t ret = ResXMLParser_next(parser);
if (ret > 0x100)
return ret - 0x100;
return ret;
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetPooledString(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
const struct ResStringPool *string_pool = ResXMLParser_getStrings(parser);
size_t len;
const char16_t *string = ResStringPool_stringAt(string_pool, index, &len);
if (!string)
return NULL;
return (*env)->NewString(env, string, len);
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetName(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_getElementNameID(parser);
if (idx < 0)
return NULL;
return Java_android_content_res_XmlBlock_nativeGetPooledString(env, this, parser_ptr, idx);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeCount(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeCount(parser);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeResource(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeNameResID(parser, index);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeIndex(JNIEnv *env, jobject this, jlong parser_ptr, jstring namespace_str, jstring name_str)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
const char16_t *namespace = NULL;
int namespace_len = 0;
if (namespace_str) {
namespace = (*env)->GetStringChars(env, namespace_str, NULL);
namespace_len = (*env)->GetStringLength(env, namespace_str);
}
const char16_t *name = (*env)->GetStringChars(env, name_str, NULL);
int name_len = (*env)->GetStringLength(env, name_str);
int ret = ResXMLParser_indexOfAttribute(parser, namespace, namespace_len, name, name_len);
if (namespace_str)
(*env)->ReleaseStringChars(env, namespace_str, namespace);
(*env)->ReleaseStringChars(env, name_str, name);
return ret;
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeStringValue(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_getAttributeValueStringID(parser, index);
if (idx < 0)
return NULL;
return Java_android_content_res_XmlBlock_nativeGetPooledString(env, this, parser_ptr, idx);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetLineNumber(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getLineNumber(parser);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeDataType(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeDataType(parser, index);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeData(JNIEnv *env, jobject this, jlong parser_ptr, jint index)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
return ResXMLParser_getAttributeData(parser, index);
}
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroyParseState(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
ResXMLParser_delete(parser);
}
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroy(JNIEnv *env, jobject this, jlong block)
{
struct ResXMLTree *tree = (struct ResXMLTree *)_PTR(block);
ResXMLTree_delete(tree);
}
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetClassAttribute(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_indexOfClass(parser);
return Java_android_content_res_XmlBlock_nativeGetAttributeStringValue(env, this, parser_ptr, idx);
}
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStyleAttribute(JNIEnv *env, jobject this, jlong parser_ptr)
{
struct ResXMLParser *parser = (struct ResXMLParser *)_PTR(parser_ptr);
int idx = ResXMLParser_indexOfStyle(parser);
struct Res_value value;
ResXMLParser_getAttributeValue(parser, idx, &value);
return value.data;
}

View File

@@ -329,6 +329,14 @@ JNIEXPORT jint JNICALL Java_android_content_res_AssetManager_loadThemeAttributeV
JNIEXPORT void JNICALL Java_android_content_res_AssetManager_dumpTheme JNIEXPORT void JNICALL Java_android_content_res_AssetManager_dumpTheme
(JNIEnv *, jclass, jlong, jint, jstring, jstring); (JNIEnv *, jclass, jlong, jint, jstring, jstring);
/*
* Class: android_content_res_AssetManager
* Method: openXmlAssetNative
* Signature: (ILjava/lang/String;)J
*/
JNIEXPORT jlong JNICALL Java_android_content_res_AssetManager_openXmlAssetNative
(JNIEnv *, jobject, jint, jstring);
/* /*
* Class: android_content_res_AssetManager * Class: android_content_res_AssetManager
* Method: getArrayStringResource * Method: getArrayStringResource

View File

@@ -20,162 +20,170 @@ JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeCreate
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetStringBlock * Method: nativeGetStringBlock
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStringBlock JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStringBlock
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeCreateParseState * Method: nativeCreateParseState
* Signature: (I)I * Signature: (J)J
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeCreateParseState JNIEXPORT jlong JNICALL Java_android_content_res_XmlBlock_nativeCreateParseState
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeNext * Method: nativeNext
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeNext JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeNext
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetNamespace * Method: nativeGetNamespace
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetNamespace JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetNamespace
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetName * Method: nativeGetName
* Signature: (I)I * Signature: (J)Ljava/lang/String;
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetName JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetName
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetText * Method: nativeGetText
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetText JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetText
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetLineNumber * Method: nativeGetLineNumber
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetLineNumber JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetLineNumber
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeCount * Method: nativeGetAttributeCount
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeCount JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeCount
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeNamespace * Method: nativeGetAttributeNamespace
* Signature: (II)I * Signature: (JI)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeNamespace JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeNamespace
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jlong, jint);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeName * Method: nativeGetAttributeName
* Signature: (II)I * Signature: (JI)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeName JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeName
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jlong, jint);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeResource * Method: nativeGetAttributeResource
* Signature: (II)I * Signature: (JI)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeResource JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeResource
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jlong, jint);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeDataType * Method: nativeGetAttributeDataType
* Signature: (II)I * Signature: (JI)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeDataType JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeDataType
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jlong, jint);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeData * Method: nativeGetAttributeData
* Signature: (II)I * Signature: (JI)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeData JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeData
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jlong, jint);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeStringValue * Method: nativeGetAttributeStringValue
* Signature: (II)I * Signature: (JI)Ljava/lang/String;
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeStringValue JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeStringValue
(JNIEnv *, jclass, jint, jint); (JNIEnv *, jclass, jlong, jint);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetIdAttribute * Method: nativeGetIdAttribute
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetIdAttribute JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetIdAttribute
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetClassAttribute * Method: nativeGetClassAttribute
* Signature: (I)I * Signature: (J)Ljava/lang/String;
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetClassAttribute JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetClassAttribute
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetStyleAttribute * Method: nativeGetStyleAttribute
* Signature: (I)I * Signature: (J)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStyleAttribute JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetStyleAttribute
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeGetAttributeIndex * Method: nativeGetAttributeIndex
* Signature: (ILjava/lang/String;Ljava/lang/String;)I * Signature: (JLjava/lang/String;Ljava/lang/String;)I
*/ */
JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeIndex JNIEXPORT jint JNICALL Java_android_content_res_XmlBlock_nativeGetAttributeIndex
(JNIEnv *, jclass, jint, jstring, jstring); (JNIEnv *, jclass, jlong, jstring, jstring);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeDestroyParseState * Method: nativeDestroyParseState
* Signature: (I)V * Signature: (J)V
*/ */
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroyParseState JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroyParseState
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/*
* Class: android_content_res_XmlBlock
* Method: nativeGetPooledString
* Signature: (JI)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_android_content_res_XmlBlock_nativeGetPooledString
(JNIEnv *, jclass, jlong, jint);
/* /*
* Class: android_content_res_XmlBlock * Class: android_content_res_XmlBlock
* Method: nativeDestroy * Method: nativeDestroy
* Signature: (I)V * Signature: (J)V
*/ */
JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroy JNIEXPORT void JNICALL Java_android_content_res_XmlBlock_nativeDestroy
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -466,20 +466,10 @@ public final class AssetManager {
*/ */
public final XmlResourceParser openXmlResourceParser(int cookie, public final XmlResourceParser openXmlResourceParser(int cookie,
String fileName) throws IOException { String fileName) throws IOException {
/* XmlBlock block = openXmlBlockAsset(cookie, fileName); XmlBlock block = openXmlBlockAsset(cookie, fileName);
XmlResourceParser rp = block.newParser(); XmlResourceParser rp = block.newParser();
block.close(); block.close();
return rp;*/ return rp;
InputStream inStream = ClassLoader.getSystemClassLoader().getResourceAsStream(fileName);
if (inStream == null) {
return null;
}
ResXmlDocument resXmlDocument = new ResXmlDocument();
resXmlDocument.readBytes(inStream);
ResXmlPullParser xpp = new ResXmlPullParser();
xpp.setResXmlDocument(resXmlDocument);
return xpp;
} }
/** /**
@@ -503,7 +493,7 @@ public final class AssetManager {
* @param fileName Name of the asset to retrieve. * @param fileName Name of the asset to retrieve.
*/ */
/*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName) throws IOException { /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName) throws IOException {
int xmlBlock; long xmlBlock;
synchronized (this) { synchronized (this) {
if (!mOpen) { if (!mOpen) {
throw new RuntimeException("Assetmanager has been closed"); throw new RuntimeException("Assetmanager has been closed");
@@ -765,17 +755,21 @@ public final class AssetManager {
int defStyleAttr, int defStyleRes, AttributeSet set, int defStyleAttr, int defStyleRes, AttributeSet set,
int[] inAttrs, int[] outValues, int[] outIndices) { int[] inAttrs, int[] outValues, int[] outIndices) {
TypedValue value = new TypedValue(); TypedValue value = new TypedValue();
ResXmlPullParser parser = (ResXmlPullParser)set; XmlResourceParser parser = (XmlResourceParser)set;
if (defStyleRes == 0 && theme != 0 && loadThemeAttributeValue(theme, defStyleAttr, value, true) >= 0) if (defStyleRes == 0 && theme != 0 && loadThemeAttributeValue(theme, defStyleAttr, value, true) >= 0)
defStyleRes = value.data; defStyleRes = value.data;
if (defStyleRes == 0 && set != null) { if (defStyleRes == 0 && set != null) {
ValueItem valueItem = parser.getAttribute(null, "style"); if (parser instanceof ResXmlPullParser) {
if (valueItem != null) { ValueItem valueItem = ((ResXmlPullParser)parser).getAttribute(null, "style");
value.type = valueItem.getType(); if (valueItem != null) {
value.data = valueItem.getData(); value.type = valueItem.getType();
if (theme != 0 && (value.type == TypedValue.TYPE_ATTRIBUTE)) value.data = valueItem.getData();
loadThemeAttributeValue(theme, value.data, value, true); if (theme != 0 && (value.type == TypedValue.TYPE_ATTRIBUTE))
defStyleRes = value.data; loadThemeAttributeValue(theme, value.data, value, true);
defStyleRes = value.data;
}
} else {
defStyleRes = parser.getStyleAttribute();
} }
} }
@@ -804,9 +798,14 @@ public final class AssetManager {
value.assetCookie = -1; value.assetCookie = -1;
found = true; found = true;
} else if (xmlCache.containsKey(resId)) { } else if (xmlCache.containsKey(resId)) {
ValueItem valueItem = parser.getResXmlAttributeAt(xmlCache.get(resId)); if (parser instanceof ResXmlPullParser) {
value.type = valueItem.getType(); ValueItem valueItem = ((ResXmlPullParser)parser).getResXmlAttributeAt(xmlCache.get(resId));
value.data = valueItem.getData(); value.type = valueItem.getType();
value.data = valueItem.getData();
} else {
value.type = XmlBlock.nativeGetAttributeDataType(((XmlBlock.Parser)parser).mParseState, xmlCache.get(resId));
value.data = XmlBlock.nativeGetAttributeData(((XmlBlock.Parser)parser).mParseState, xmlCache.get(resId));
}
value.resourceId = 0; value.resourceId = 0;
value.assetCookie = -1; value.assetCookie = -1;
if (value.type != TypedValue.TYPE_ATTRIBUTE) if (value.type != TypedValue.TYPE_ATTRIBUTE)
@@ -888,9 +887,7 @@ public final class AssetManager {
boolean resolve); boolean resolve);
/*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix); /*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix);
private /*native*/ final int openXmlAssetNative(int cookie, String fileName) { private native final long openXmlAssetNative(int cookie, String fileName);
return openAsset("../" + fileName, 0);
}
private native final String[] getArrayStringResource(int arrayRes); private native final String[] getArrayStringResource(int arrayRes);
private native final int[] getArrayStringInfo(int arrayRes); private native final int[] getArrayStringInfo(int arrayRes);

View File

@@ -1376,7 +1376,7 @@ public class Resources {
// To support generic XML files we will need to manually parse // To support generic XML files we will need to manually parse
// out the attributes from the XML file (applying type information // out the attributes from the XML file (applying type information
// contained in the resources and such). // contained in the resources and such).
ResXmlPullParser parser = (ResXmlPullParser)set; XmlResourceParser parser = (XmlResourceParser)set;
mAssets.applyStyle(theme, defStyleAttr, defStyleRes, mAssets.applyStyle(theme, defStyleAttr, defStyleRes,
set, attrs, array.mData, array.mIndices); set, attrs, array.mData, array.mIndices);
array.mRsrcs = attrs; array.mRsrcs = attrs;
@@ -1495,7 +1495,7 @@ public class Resources {
// To support generic XML files we will need to manually parse // To support generic XML files we will need to manually parse
// out the attributes from the XML file (applying type information // out the attributes from the XML file (applying type information
// contained in the resources and such). // contained in the resources and such).
ResXmlPullParser parser = (ResXmlPullParser)set; XmlResourceParser parser = (XmlResourceParser)set;
mAssets.applyStyle(0, 0, 0, mAssets.applyStyle(0, 0, 0,
set, attrs, array.mData, array.mIndices); set, attrs, array.mData, array.mIndices);

View File

@@ -39,7 +39,7 @@ import java.util.Arrays;
*/ */
public class TypedArray { public class TypedArray {
private final Resources mResources; private final Resources mResources;
/*package*/ ResXmlPullParser mXml; /*package*/ XmlResourceParser mXml;
/*package*/ int[] mRsrcs; /*package*/ int[] mRsrcs;
/*package*/ int[] mData; /*package*/ int[] mData;
/*package*/ int[] mIndices; /*package*/ int[] mIndices;
@@ -156,7 +156,12 @@ public class TypedArray {
if (type == TypedValue.TYPE_STRING) { if (type == TypedValue.TYPE_STRING) {
final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE]; final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE];
if (cookie < 0) { if (cookie < 0) {
return mXml.getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]).get(); if (mXml instanceof ResXmlPullParser)
return ((ResXmlPullParser )mXml).getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]).get();
else {
Thread.dumpStack();
System.exit(-1);
}
} }
} }
return null; return null;
@@ -695,9 +700,15 @@ public class TypedArray {
final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE]; final int cookie = data[index + AssetManager.STYLE_ASSET_COOKIE];
if (cookie < 0) { if (cookie < 0) {
if (mXml != null) { if (mXml != null) {
ResXmlString xmlString = mXml.getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]); if (mXml instanceof ResXmlPullParser) {
if (xmlString != null) ResXmlString xmlString = ((ResXmlPullParser)mXml).getResXmlDocument().getStringPool().get(data[index + AssetManager.STYLE_DATA]);
return xmlString.get(); if (xmlString != null)
return xmlString.get();
} else {
CharSequence string = ((XmlBlock.Parser)mXml).getPooledString(data[index + AssetManager.STYLE_DATA]);
if (string != null)
return string;
}
} }
if (data[index + AssetManager.STYLE_RESOURCE_ID] != 0) { if (data[index + AssetManager.STYLE_RESOURCE_ID] != 0) {
return mResources.mAssets.getResourceText(data[index + AssetManager.STYLE_RESOURCE_ID]); return mResources.mAssets.getResourceText(data[index + AssetManager.STYLE_RESOURCE_ID]);

View File

@@ -72,7 +72,7 @@ final class XmlBlock {
} }
/*package*/ final class Parser implements XmlResourceParser { /*package*/ final class Parser implements XmlResourceParser {
Parser(int parseState, XmlBlock block) { Parser(long parseState, XmlBlock block) {
mParseState = parseState; mParseState = parseState;
mBlock = block; mBlock = block;
block.mOpenCount++; block.mOpenCount++;
@@ -168,8 +168,7 @@ final class XmlBlock {
return id >= 0 ? mStrings.get(id).toString() : ""; return id >= 0 ? mStrings.get(id).toString() : "";
} }
public String getName() { public String getName() {
int id = nativeGetName(mParseState); return nativeGetName(mParseState);
return id >= 0 ? mStrings.get(id).toString() : null;
} }
public String getAttributeNamespace(int index) { public String getAttributeNamespace(int index) {
int id = nativeGetAttributeNamespace(mParseState, index); int id = nativeGetAttributeNamespace(mParseState, index);
@@ -200,11 +199,9 @@ final class XmlBlock {
return mEventType == START_TAG ? nativeGetAttributeCount(mParseState) : -1; return mEventType == START_TAG ? nativeGetAttributeCount(mParseState) : -1;
} }
public String getAttributeValue(int index) { public String getAttributeValue(int index) {
int id = nativeGetAttributeStringValue(mParseState, index); String value = nativeGetAttributeStringValue(mParseState, index);
if (DEBUG) if (value != null)
System.out.println("getAttributeValue of " + index + " = " + id); return value;
if (id >= 0)
return mStrings.get(id).toString();
// May be some other type... check and try to convert if so. // May be some other type... check and try to convert if so.
int t = nativeGetAttributeDataType(mParseState, index); int t = nativeGetAttributeDataType(mParseState, index);
@@ -423,8 +420,7 @@ final class XmlBlock {
return id >= 0 ? mStrings.get(id).toString() : null; return id >= 0 ? mStrings.get(id).toString() : null;
} }
public String getClassAttribute() { public String getClassAttribute() {
int id = nativeGetClassAttribute(mParseState); return nativeGetClassAttribute(mParseState);
return id >= 0 ? mStrings.get(id).toString() : null;
} }
public int getIdAttributeResourceValue(int defaultValue) { public int getIdAttributeResourceValue(int defaultValue) {
@@ -451,10 +447,12 @@ final class XmlBlock {
} }
/*package*/ final CharSequence getPooledString(int id) { /*package*/ final CharSequence getPooledString(int id) {
return mStrings.get(id); if (id < 0)
return null;
return nativeGetPooledString(mParseState, id);
} }
/*package*/ int mParseState; /*package*/ long mParseState;
private final XmlBlock mBlock; private final XmlBlock mBlock;
private boolean mStarted = false; private boolean mStarted = false;
private boolean mDecNextDepth = false; private boolean mDecNextDepth = false;
@@ -472,14 +470,15 @@ final class XmlBlock {
* are doing! The given native object must exist for the entire lifetime * are doing! The given native object must exist for the entire lifetime
* of this newly creating XmlBlock. * of this newly creating XmlBlock.
*/ */
XmlBlock(AssetManager assets, int xmlBlock) { XmlBlock(AssetManager assets, long xmlBlock) {
mAssets = assets; mAssets = assets;
mNative = xmlBlock; mNative = xmlBlock;
mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false); // mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false);
mStrings = null;
} }
private final AssetManager mAssets; private final AssetManager mAssets;
private final int mNative; private final long mNative;
/*package*/ final StringBlock mStrings; /*package*/ final StringBlock mStrings;
private boolean mOpen = true; private boolean mOpen = true;
private int mOpenCount = 1; private int mOpenCount = 1;
@@ -487,26 +486,27 @@ final class XmlBlock {
private static final native int nativeCreate(byte[] data, private static final native int nativeCreate(byte[] data,
int offset, int offset,
int size); int size);
private static final native int nativeGetStringBlock(int obj); private static final native int nativeGetStringBlock(long obj);
private static final native int nativeCreateParseState(int obj); private static final native long nativeCreateParseState(long obj);
/*package*/ static final native int nativeNext(int state); /*package*/ static final native int nativeNext(long state);
private static final native int nativeGetNamespace(int state); private static final native int nativeGetNamespace(long state);
/*package*/ static final native int nativeGetName(int state); /*package*/ static final native String nativeGetName(long state);
private static final native int nativeGetText(int state); private static final native int nativeGetText(long state);
private static final native int nativeGetLineNumber(int state); private static final native int nativeGetLineNumber(long state);
private static final native int nativeGetAttributeCount(int state); private static final native int nativeGetAttributeCount(long state);
private static final native int nativeGetAttributeNamespace(int state, int idx); private static final native int nativeGetAttributeNamespace(long state, int idx);
private static final native int nativeGetAttributeName(int state, int idx); private static final native int nativeGetAttributeName(long state, int idx);
private static final native int nativeGetAttributeResource(int state, int idx); private static final native int nativeGetAttributeResource(long state, int idx);
private static final native int nativeGetAttributeDataType(int state, int idx); static final native int nativeGetAttributeDataType(long state, int idx);
private static final native int nativeGetAttributeData(int state, int idx); static final native int nativeGetAttributeData(long state, int idx);
private static final native int nativeGetAttributeStringValue(int state, int idx); private static final native String nativeGetAttributeStringValue(long state, int idx);
private static final native int nativeGetIdAttribute(int state); private static final native int nativeGetIdAttribute(long state);
private static final native int nativeGetClassAttribute(int state); private static final native String nativeGetClassAttribute(long state);
private static final native int nativeGetStyleAttribute(int state); private static final native int nativeGetStyleAttribute(long state);
private static final native int nativeGetAttributeIndex(int state, String namespace, String name); private static final native int nativeGetAttributeIndex(long state, String namespace, String name);
private static final native void nativeDestroyParseState(int state); private static final native void nativeDestroyParseState(long state);
private static final native String nativeGetPooledString(long state, int id);
private static final native void nativeDestroy(int obj); private static final native void nativeDestroy(long obj);
} }