6

I need to dynamically load a xml layout from the server. LayoutInflater has inflate methods that use a XmlPullParser. I've tried that, but it doesn't work.

Looking into the Android source code, it turns out those inflate methods are called with a XmlResourceParser. The implementation Android uses is XmlBlock.Parser, but that is not a public API.

Is there a XmlResourceParser public implementation I can use?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Mugur
  • 1,019
  • 9
  • 21

4 Answers4

4

You can use a traditional XmlPullParser like described in Android documentation :

InputStream yourRemoteLayout = ...;
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
parser.setInput(yourRemoteLayout, "someEncoding");
AttributeSet attributes = Xml.asAttributeSet(parser);

Please see what's explained in XmlPullParser documentation for more details.


Edit : From LayoutInflater#inflate() documentation :

Important   For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime.

What I guess, is that maybe you should make your own implementation of LayoutInflater.Factory2 if Android's own only rely on preprocessed resources.

Antoine Marques
  • 1,379
  • 1
  • 8
  • 16
  • In the example you gave, myResource is an int. I do not have that int as the resource was not part of the app. – Mugur Sep 09 '13 at 11:26
  • The inflate method uses a XmlResourceParser. And the only implementation of that is XmlBlock.Parser which uses some native code and is not part of the public API. Hence, my issue. – Mugur Sep 09 '13 at 11:32
  • Oh sorry, i didn't watch carrefully the int. I'll search some workaround. I checked about the XmlResourceParser you talked and didn't found it. The documentation speaks of an XmlPullParser and the source code doesn't make any attempt to cast it (i've look 4.0.3, but i might have missed something). Could you give some more precise reference for the XmlResourceParser ? – Antoine Marques Sep 09 '13 at 12:00
  • http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/view/LayoutInflater.java#LayoutInflater.inflate%28int%2Candroid.view.ViewGroup%2Cboolean%29 – Mugur Sep 09 '13 at 12:02
  • http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/content/res/XmlResourceParser.java#XmlResourceParser – Mugur Sep 09 '13 at 12:02
  • I've read my reply once again. I've saw it is not clear though it is right : i had like to say : you can obtain an instance of XmlPullParser using its factory, then set its input, then get it as an AttributeSet. I'll edit my reply. – Antoine Marques Sep 09 '13 at 13:08
  • As for the links you're posting, I suggest you use directly LayoutInflater.inflate(XmlPullParser, ViewGroup, boolean), with the obtained XmlPullParser, which will get you rid of your XmlResourceParser problem. – Antoine Marques Sep 09 '13 at 13:15
2

in fact, you CAN NOT load xml layout dynamically. android system DOES NOT need a XmlResourceParser. when android ui system inflate an resource, it just convert the parser to it's private implementation, a binary xml source parser (i forgot the class name).

1 year ago, i tried this, spent many many times. so, don't waste your time as me again.

afpro
  • 1,103
  • 7
  • 12
  • If you take a look at the Android source code, you will notice that the LayoutInflater.inflate method gets called with a XmlResourceParser as a parameter. In theory, a implementation of the XmlResourceParser will solve my problem, but I couldn't find anywhere the specifications for the Android binary xml format. So, I do not agree with you that it cannot be done, it's just very complicated at this point in time, so, I agree with your second point that it's a waste of time to try to do it now. – Mugur Sep 11 '13 at 14:41
  • i know, but it just look at View's constructor, it process `AttributeSet` by `Context.obtainStyledAttributes`, and then `Resources.obtainStyledAttributes`. in this method: `XmlBlock.Parser parser = (XmlBlock.Parser)set`. if you implement XmlPullParser, how can you provide this object to view? or you could ignore AttributeSet and implement them all by yourself. but notice that, View's constructor use many `@hide` api you can't access. – afpro Sep 12 '13 at 00:19
2

YES, right now is possible with ItsNat Droid.

Take a look to this summary:

https://groups.google.com/forum/#!topic/itsnat/13nl0P12J_s

It is still under heavy development but most important features are already implemented.

jmarranz
  • 6,459
  • 2
  • 21
  • 10
1

For performance reasons, view inflation relies heavily on pre-processing of XML files that is done at build time. Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime.

That isn't to say it can't be done. But you will need to run the build tools on the xml file to get it into the right format. Then you can probably mock a 'Context' and 'Resources' that returns the downloaded data when used in a 'LayoutInflator'

FunkTheMonk
  • 10,908
  • 1
  • 31
  • 37