给定 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中的汉字

xmlPullParser的使用

XML的XmlPullParser解析

如何在不满足给定条件的情况下创建一系列变量并将它们存储在列表中?

XmlPullParser(安卓推荐)