I thinks it's probably not possible for security reason but just want to be sure: is it possible to create layout in Android from an external XML file?
To be exactly: I'm creating XML output with XSL on a remote server. I could create the necessary layout direct on the server and then download it to my Android App.
It is impossible. XML layouts in Android are NOT stored as XML. For performance reasons, they are pre-processed during compilation and stored in binary form, and layout inflater only understands that binary form rather than xml.
Of course you can create Views dynamic at runtime, while I'm not shure, that this is the best solution. If you have a look at the internals of Android, every View which is created through XML is called with a Constructor with two parameters: Context and - even more interesting for you - an AttributeSet. I think you have a lot of work with parsing it, while keeping track of the right format.
You could at least set the values and build your views yourself in Java depending on Server output.
YES, right now is possible with ItsNat Droid, take a look:
https://groups.google.com/forum/#!topic/itsnat/13nl0P12J_s
It is still under heavy development but most important features are already implemented.
it's possible, but I found way to load only simple layout:
Resources resources=context.getPackageManager().getResourcesForApplication(targetPackage);
int resID = resources.getIdentifier("widget_layout" , "layout", TARGET_PACKAGE);
XmlResourceParser parser = resources.getLayout(resID);
View themeLayout = LayoutInflater.from(this).inflate(parser, null);
Maybe the inflate function of the LayoutInflator works for you.
EDIT: doesn't work yet it seems.
Related
I'm developing a generic Android application that needs to get XML files from the server and set its contentview accordingly.
The XML files can be as simple as a relative layout with a textview or much more complex, that's really not relevant. The goal is to simply fetch XML files externally and display them or receive a string from the server, create a XML file locally on runtime and use it, both will do.
I've been looking for a while now and I didn't find any solution. Is there a way to do this?
According to this post which references Android's LayoutInflater doc; it is not possible since there's some "pre-processing of XML files that is done at build time."
In short, you can't use a regular xml pulled externally to inflate.
I was wondering if it was possible to set a view through a remote xml file. I had a look on the web and I found this post here on stackoverflow. Reading the answers I got I can't do it.
Why?
XML layout files are pre-processed at build time in order to provide efficient inflation of complex layouts.
Although there are LayoutInflator methods which take a path to an XML file, they have never been implemented.
In other words, unless your XML layout file is pre-processed and packaged at build time into your APK, then it can't be done.
There is one possibility, however, you could build an XML parser to parse your 'external' XML layout file and create your layout dynamically using Java code - not impossible but you're pretty much on your own if you choose to do that.
In Android reference, it says
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; it only works with an XmlPullParser
returned from a compiled resource (R.something file.)
Details here
if it really causes performance reasons why Android developers don't solve this problem? Is it any solution about it? Can I use a XML parser before inflate layout file?
Android's string processing is slow. So they actually do solve it by pre-processing the xml file. When you think about it, your layout xmls should be static cause any change you made on them will most likely also cause code changes. What is the point of being able to inflate a remote layout file if you can't use it without code changes especially when the string processing is that slow.
A better solution might be, writing a class file that creates the layout you need, put it in somewhere lets say internet. Than on the runtime you can download that file, load it as a class dynamically using reflection and use it.
Check out this links for further information.
Java Reflection - Dynamic Class Loading and Reloading
How to load a Java class dynamically on android/dalvik?
Whats the best way for me to take an android XML layout file and automatically generate the equivalent Java code? Does a tool like JAXB work and if so how do I use it?
It's an interesting idea, though a bit useless IMHO. Why would one want to do it? Inflating an XML is very fast operation and hides a lot of complexity - for example it takes into account what is the current DisplayMetrics and recalculates layout parameters (width/height) appropriately to the density and size of the screen... It's also very fast because it does not actually require XML parsing - parsing is done at compilation time and what is actually stored by android is a binary version of the layout which is optimized for efficiency (that's why you cannot build layout XML dynamically from an XML file).
If you would like to modify the Java code and add/remove some elements then it is much more efficient to inflate the XML and then do all the modifications -less clutter simpler code and all the calculations are done for you...
Whats the best way for me to take an android XML layout file and automatically generate the equivalent Java code?
Step #1: Parse the XML.
Step #2: Generate the Java code. You'll have to pray that you can build your own AttributeSet implementation that works with your generated code, otherwise this will be a very complex problem.
Does a tool like JAXB work
AFAIK, JAXB needs an XML Schema, and there is no such schema possible for the Android layout file.
Whatever problem you're trying to solve this way, there's probably a better solution.
I just want a simple way to take an android xml layout and pass it to, say, a command line tool to generate the equivalent Java.
I seriously doubt that this will be "simple" for any reasonable definition of the term.
I want to write an app where (at least for now) the content is always the same but the layout is loaded dynamically at run time based on a user preference. Essentially I want the app to apply a "skin" which may look completely different to other skins.
I found some tutorials using SAXparser:
http://www.androidpeople.com/android-xml-parsing-tutorial-using-saxparser/
http://twigstechtips.blogspot.com/2010/12/android-how-to-parse-xml-string.html
and can imagine writing something from scratch that recognizes all the standard xml layout tags and then dynamically loads each part of the layout. But that's a lot of work to do from scratch! Surely this functionality is available in android, or surely someone has written some open source code which can be run at the start of your activity's onCreate method, which takes in an xml file and sets your layout?
I found a similar but unsatisfactorily answered question here:
How to create a layout file programmatically
which makes me think that since setContentView must take an integer resourceID as its argument, the fact that these are pre-baked at compile time might be a problem. (setContentView may also take a View object as its argument, but I don't want a ton of if statements and to pass it each View object one by one, I want some code that inputs an xml file or xml string and sets the content view.)
Maybe I'm way off track. Is there another way to do this? I would think that the ability to have an app with dynamically loaded skins is important.
Thanks!
I had similar requirements and tried the same approach - it does not work.
Documentation clearly states this: http://developer.android.com/reference/android/view/LayoutInflater.html
Update:
Since OP needs to load XML layouts created at runtime:
Possibly this could be done, by creating XML layout files, copying them to dummy project, create .apk and then load apk on to device.
DexClassLoader can be then used to load classes inside apk.
well, android makes the hard work for you, but no all the the work....
first that all you have to forget about parsing xml layouts... instead you can make skeletons layout, that manages his inner childs position, size, etc... and later inflate that 'skeleton' xml with LayoutInflater and obtain a View instance...
When you have that View instance then you can do what you want with it, applying the users preferences like backgrouds, foregrounds colors, position, sizes, etc...
maybe i dont understand your question but you can get any view inflated from a xml resource at compile-time and later apply other style or set another propertys
It seems it is impossible to load the layout & change the skin dynamically according to the doc :
Therefore, it is not currently possible to use LayoutInflater with an XmlPullParser over a plain XML file at runtime; it only works with an XmlPullParser returned from a compiled resource (R.something file.)
http://developer.android.com/reference/android/view/LayoutInflater.html