给定 XmlPullParser 作为输入,如何创建 LayoutInflater?
Posted
技术标签:
【中文标题】给定 XmlPullParser 作为输入,如何创建 LayoutInflater?【英文标题】:How to create a LayoutInflater Given XmlPullParser as input? 【发布时间】:2012-03-28 15:51:15 【问题描述】:我有一个字符串输入,其中包含一个带有字符串 Fromat 的 Layout.xml。
// String that contains the Layout.xml :
String concat ;
// Create the XmlPullParser from the String format
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput( new StringReader (concat) );
// create le The LayoutInflater
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View myView = inflater.inflate(xpp, null);
我遇到了这个错误:
03-12 08:23:12.876: W/System.err(937): android.view.InflateException: START_TAG http://schemas.android.com/apk/res/androidandroid:orientation='vertical' http://schemas.android.com/apk/res/androidandroid:layout_width='fill_parent' http://schemas.android.com/apk/res/androidandroid:layout_height='fill_parent'>@1:226 在 java.io.StringReader@44f50508 中:膨胀类时出错
请帮忙?
【问题讨论】:
【参考方案1】:Inflater 似乎只接受 XmlBlock。
我已经写了一个方法来做到这一点,你可以参考项目站点: https://github.com/liudongmiao/preference-fragment-compat/blob/master/src/me/piebridge/android/preference/PreferenceFragment.java#L202
主要代码如下:
// byte[] data = ...
// bytes of compiled xml (unzip the apk, get the bytes from res/layout*/*.xml)
// XmlBlock block = new XmlBlock(data);
Class<?> clazz = Class.forName("android.content.res.XmlBlock");
Constructor<?> constructor = clazz.getDeclaredConstructor(byte[].class);
constructor.setAccessible(true);
Object block = constructor.newInstance(data);
// XmlPullParser parser = block.newParser();
Method method = clazz.getDeclaredMethod("newParser");
method.setAccessible(true);
XmlPullParser parser = method.invoke(block);
【讨论】:
我正在尝试在您的存储库中使用您的PreferenceFragment.getParser(String xml)
方法。我看到您将public static final String LAYOUT
传递给您的getParser()
方法并将LAYOUT
膨胀为View
。你是如何生成String LAYOUT
的?我猜您以某种方式对布局的编译代码进行了编码,但我想知道详细信息,以便我可以将自己的布局编码为与 LAYOUT
... 相同的格式?
@Wess 我在 cmets 中写过。再读一遍。
谢谢@liudongmiao。我已按照您的步骤操作,但我总是收到NullPointerException: Attempt to invoke interface method 'java.lang.String org.xmlpull.v1.XmlPullParser.getPositionDescription()' on a null object reference
。我的步骤:解压缩 apk -> 将编译后的布局复制到项目中的 res/raw -> 在运行时将布局文件内容读取到 String -> 将 String 转换为 byte[] data
并传递到 Object block = constructor.newInstance(data);
。不知道我做错了什么?任何帮助将不胜感激。
我实现了你的代码,但在运行时,我得到了 InvocationTargetException。在记录比异常高一行我看到关于 XmlBlock 的一行:Bad XML block: header size 28024 or total size 1702240364 is larger than data size 2757
@liudongmiao - 如果您从上面的 cmets 回答用户的问题,那就太好了。我发现你的方法很有趣,但我还没有尝试过。这种方法仍然有效且有效吗?来自预编译 XML 文件的二进制代码是否包含为每个视图预先分配的一些 ID?如果是这样,如果这样的布局被膨胀到另一个视图中,这可能会导致与现有 ID 的冲突。您能否用有关二进制数据、方法的使用和限制的更多信息更新您的答案?谢谢!以上是关于给定 XmlPullParser 作为输入,如何创建 LayoutInflater?的主要内容,如果未能解决你的问题,请参考以下文章
Android:如何获取 TAG 的值:使用 XmlPullParser
如何使用xmlpullparser解析android中的汉字