Android: 如何从assets目录加载xml文件?

16
我在加载assets目录下的xml文件时遇到了问题。我使用了同一行代码(只是更改了路径),但结果不同(有时正常,有时出现NPE /文件损坏)。文件“castle1.tmx”(一个xml文件)被复制到了两个位置:
  • res/xml/castle1.tmx
  • assets/level/castle1.tmx
使用以下代码可以解决问题:
XmlResourceParser xrp = ctx.getAssets().openXmlResourceParser("res/xml/castle1.tmx");

使用这一行时,它不会:

XmlResourceParser xrp = ctx.getAssets().openXmlResourceParser("assets/level/castle1.tmx");

我得到以下结果:

04-05 21:46:40.940: WARN/ResourceType(29056): Bad XML block: header size 28024 or total size 1702240364 is larger than data size 70441
04-05 21:46:40.940: ERROR/TestParser(29056): Unable to read resource file
04-05 21:46:40.940: WARN/System.err(29056): java.io.FileNotFoundException: Corrupt XML binary file
04-05 21:46:40.940: WARN/System.err(29056):     at android.content.res.AssetManager.openXmlAssetNative(Native Method)
04-05 21:46:40.944: WARN/System.err(29056):     at android.content.res.AssetManager.openXmlBlockAsset(AssetManager.java:485)
04-05 21:46:40.944: WARN/System.err(29056):     at android.content.res.AssetManager.openXmlResourceParser(AssetManager.java:453)
04-05 21:46:40.944: WARN/System.err(29056):     at android.content.res.AssetManager.openXmlResourceParser(AssetManager.java:442)
04-05 21:46:40.944: WARN/System.err(29056):     at game.test.MapLoader.<init>(MapLoader.java:73)

文件在两种情况下都找到了......只是我似乎无法使用这种方法从资产目录读取它。

有什么办法可以从资源目录加载我的 XML 文件吗?

谢谢

5个回答

19
res/ 文件夹中,所有的 xml 文件都是预编译过的,而在 assets/ 文件夹中则没有。因此,你无法使用 openXmlResourceParser() 来处理非预编译资源。取而代之地,可以使用 open() 方法,并通过 InputStream 读取文件。

那么我应该使用什么来解析/assets/blah.xml中的XML文件?我必须手动搜索关键字和属性,创建自己的解析器吗?没有其他选择吗? - freeaks
你可以随时使用Java提供的解析器,例如XPath。 - Gerard

16

我成功地从assets目录(assets/level/castle1.tmx)加载和解析了我的xml文件。

这是我所做的:

将以下内容替换为:

  XmlResourceParser xrp = ctx.getResources().getXml(ctx.getResources().getIdentifier(name, "xml", ctx.getPackageName()));

通过以下方式:

  InputStream istr = context.getAssets().open("level/"+name+".tmx");
  XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); 
  factory.setNamespaceAware(true); 
  xrp = factory.newPullParser(); 
  xrp.setInput(istr, "UTF-8");  

然后我所需要做的就是编辑一些getAttributeIntValue()行:

  int a = xrp.getAttributeIntValue(null, "width",0));

变成这个:

  int a = Integer.parseInt(xrp.getAttributeValue(null, "width"));

其余的全部都没有修改就能正常工作 :) 这个类是用来解析 tiled xml/map 文件以构建我的游戏关卡。 之前,它使用 res/ 能正常工作,但我想试着将所有文件放到 assets/ 中。 现在它也能正常工作了 :)

感谢帮助


4
原因是您正在尝试加载二进制XML文件(您的错误是java.io.FileNotFoundException: Corrupt XML binary file)。所有Android XML文件(布局、字符串等)存储在res中,在编译项目时会自动编译为二进制XML。位于资产中的XML文件被视为标准XML文件,因此不会被编译为二进制XML。总之:Android XML文件必须位于res文件夹中。您只能在资产文件夹中存储纯文本XML(而不是布局文件等)。

那么,如何解析位于assets/目录中的XML文件?我应该将整个XML文件作为一个大字符串加载,然后手动开始搜索关键字、属性和诸如此类的内容吗? - freeaks
他所说的不是关于Android XML文件,而是关于他自己的XML格式。 - Heiko Rupp
@Heiko 抱歉 - 在这种情况下, 应该能够从资产中加载标准的 XML 文件。 - Joseph Earl

3

0
    Resources resourcesForApplication = activity.getPackageManager().getResourcesForApplication(activity.getPackageName());
    AssetManager assets = resourcesForApplication.getAssets();
    InputStream xmlInputStream = assets.open("templates/horizontal/ybard/front/ybcard.xml");

    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    factory.setNamespaceAware(true);
    XmlPullParser parseXml = factory.newPullParser();

    parseXml.setInput(xmlInputStream ,"UTF-8");



    while ((eventType = parseXml.nextToken()) != XmlPullParser.END_DOCUMENT){

        if (eventType == XmlPullParser.START_TAG && parseXml.getName().equals("layers")) {

            String documentWidth = parseXml.getAttributeValue(0);
            String documentHeight = parseXml.getAttributeValue(1);
            ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接