Android XML Weirdness

Here’s something weird I noticed while fooling around with the Android SDK:

<?xml version="1.0" encoding="UTF-8"?>
<TextView xmlns:a="http://schemas.android.com/apk/res/android"
    a:layout_width="fill_parent" 
    a:layout_height="wrap_content" 
    a:text="Hello World"
    />

If the weirdness doesn’t strike you, look twice.

The attributes are in the Android namespace but the elements are in no namespace at all. This is exactly the reverse of the usual pattern. Can anyone explain this? I’m not sure it’s wrong, but it’s certainly strange, and violates the principle of least surprise.

16 Responses to “Android XML Weirdness”

  1. John Cowan Says:

    That pattern shows up when you want to add annotations to otherwise arbitrary documents. For example, XLink exists only in the form of attributes, and XSLT has the xslt:version attribute to allow you to annotate an ordinary document as its own spreadsheet.

    I’m not saying that’s the story here: I don’t know.

  2. Elliotte Rusty Harold Says:

    Yes, but here it’s all Android and nothing but Android. The elements seem as constrained as the attributes. Possibly at some point these attributes may be added in other documents (XHTML?) but that’s just a wild guess. I haven’t yet found any evidence of that. I don’t understand why this isn’t just:

    <?xml version="1.0" encoding="UTF-8"?>
    <TextView xmlns="http://schemas.android.com/apk/res/android"
        layout_width="fill_parent"
        layout_height="wrap_content"
        text="Hello World"
        />
  3. Dianne Hackborn Says:

    This is intentional. The tag is used to find the Java class to be instantiated. The attributes are parsed by that class and all of its base classes. Because the class inheritance can cross multiple entities (the core Android platform, and the most derived class in your own application for example), the attributes are tagged with the namespace of the party it is intended for.

    This way in your own application you can make a subclass of, say, TextView, and define your own custom attributes for that subclass, without any worry that they will conflict with an attribute name used by the platform now or in the future.

    Here is an example of what such a case could look like:

    <?xml version=”1.0″ encoding=”UTF-8″?>
    <com.me.myapp.MyTextView
    xmlns:android=”http://schemas.android.com/apk/res/android”
    xmlns:app=”http://schemas.android.com/apk/res/com.me.myapp”
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    android:text=”Hello World”
    app:mySpecialFeature=”true”
    />

  4. Christof Says:

    Also at least a bit strange is that elements and attributes use a different Syntax (CamelCase versus under_scores). Consistency would expect something else.

    Also @text should ideally be an element if at any later stage mixed content would be added this will be a problem (maybe not too likely for mobile phones but why not?).

  5. Elliotte Rusty Harold Says:

    OK. That makes some sense. It’s still a little weird though. Essentially you’re mixing two different namespacing mechanisms: XML’s and Java’s. I would think one would do. And even if you need both, I still think a default namespace for Android would help when (not if) this stuff needs to be integrated with other XML vocabularies.

    Also, why is the element in the example above TextView instead of android.widget.TextView? (Also weird that this is not com.android.widget.textview)

  6. Dianne Hackborn Says:

    Also at least a bit strange is that elements and attributes use a different Syntax (CamelCase versus under_scores).

    This is a convention to indicate attributes that are interpreted by the parent of the view (its layout manager, hence the layout_ prefix) vs. the view itself. Yes, the document could be structured to separate these into different tags, but that makes the resulting data larger and more complicated to parse. Parsing these files is one of the very performance critical aspects of the system, so that and other requirements tend to trump philosphically pristine XML.

    (Note that these XML documents are actually parsed at build time into a binary representation that is what is really read on the device. In addition to turning the XML structure into a binary format, we also do pre-processing such as assigning unique identifiers to attribute names based on their namespaces to avoid string comparisons, looking up attribute values like “@string/mystring” to the resource identifier they are referencing, converting integer and color values like “#fff” to 32-bit ints, stripping unnecessary things like comments, etc. So in a way you can look at the XML as our current way to generate the “real” raw resource data, which happens to be designed to map directly to the facilities XML provides.)

    Also @text should ideally be an element if at any later stage mixed content would be added this will be a problem

    The example here is actually simplistic. Usually what this value will be is a reference to a string resource (such as “@string/mystring”). That string resource can contain complex styling information (which again happens to be built with XML but results in a different, compact binary format after being compiled). We don’t care about strongly supporting strings that are within the layout file, because these usually need to be localized so need to come from somewhere else.

    Essentially you’re mixing two different namespacing mechanisms: XML’s and Java’s. I would think one would do. And even if you need both, I still think a default namespace for Android would help when (not if) this stuff needs to be integrated with other XML vocabularies.

    This is certainly a valid criticism. My only defense is that what we really care about are the Java namespaces (or actually application/resource namespaces, which happen to use the same Java convention), and what we are doing is leveraging the general XML namespace support as a means to identify them. So we have defined a particular XML namespace prefix, under which all of the application namespaces can be defined. When our XML compiler sees something in that namespace prefix, it knows how to extract the application package name from it, and use that to look up and assign resource identifiers belonging to it.

    We deliberately aren’t using a default namespace, because we want to be as strict as possible about names and namespaces to catch errors at build time instead of run time.

    Also, why is the element in the example above TextView instead of android.widget.TextView? (Also weird that this is not com.android.widget.textview)

    The layout inflator takes care of looking in the android.widget package for you as a convenience, so you don’t need to write out the fully qualified name all of the time. This is very useful since most layouts are predominantly composed of system classes. There is also a facility for applications to provide shorthand aliases for their own classes if there are some they are using extensively.

    The package is android.widget, because android.* is the root package of the core Android frameworks, similar to how java.* are the packages for the core Java classes.

  7. Khaing Says:

    Dear all,
    I have a problem with Android TextView.
    I want to get only number in my TextView when user input data from keypad. How can I do that?
    Example, if user press A from keyboard TextView will show 1 or other digit.
    I am interested in Android Platform, so explain to me, if u have a time. thanks you

  8. Thaw Says:

    Write EditText tag to your desire layout like that as following:

    Try on!

  9. Thaw Says:

    //EditText android:id=”@+id/body”
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    android:typeface=”serif”
    android:phoneNumber=”true”
    android:singleLine=”True” />

  10. Eric Raymond Says:

    Shame. What Elliotte suggests is a more efficient and readable language. Let the parser work a little harder at build time. Why should the language suffer for the sake of the compiler (or to handle the less common need to fully qualify attributes)?

    I would prefer the following syntax for the case of a custom class:

    One can only dream. In the mean-time, “android:” can be shortened to “a:” as a band-aid.

  11. Eric Raymond Says:

    Rats. Looks like the XML was stripped out. Try again:

    Shame. What Elliotte suggests is a more efficient and readable language. Let the parser work a little harder at build time. Why should the language suffer for the sake of the compiler (or to handle the less common need to fully qualify attributes)?

    I would prefer the following syntax for the case of a custom class (where attributes are always evaluated in terms of their containing class unless fully qualfied):

    <LinearLayout

    xmlns=”http://schemas.android.com/apk/res/android”
    xmlns:app=”com.me.myapp.*”

    orientation=”vertical”
    layout_width=”fill_parent”
    layout_height=”fill_parent”
    >

    <app:MyTextView

    layout_width=”fill_parent”
    layout_height=”wrap_content”
    text=”Hello World”
    mySpecialFeature=”true”

    />

    </LinearLayout>

    One can only dream. In the mean-time, “android:” can be shortened to “a:” as a band-aid.

    <LinearLayout

    xmlns:a=”http://schemas.android.com/apk/res/android”
    a:orientation=”vertical”
    a:layout_width=”fill_parent”
    a:layout_height=”fill_parent”
    >

  12. Andy Says:

    The same way you can say that choosing following numbers in lottery is strange and unlikely to win – but what is strange as far as you understand it?

  13. Mike Says:

    Sorry, but this explanation is completely bunk. Every other XML-based component framework I have ever used has done it *backwards* of this, without any resulting problems. Microsoft, Adobe, and Mozilla all got it right, but Google got caught up in some technical debate and ended up making things worse for developers. Android team, you screwed up, it’s time to admit your error and fix it.

  14. Fırat KÜÇÜK Says:

    Aproach is compiler friendly but not developer friendly.

  15. bulldy Says:

    Sorry, but I have to add myself among the users who are unsatisfied with this explanation. Validating XML namespaces is trivial (especially if it is only done at build time). As the producers of the XML, we would know which namespace is most commonly used in our document, and therefore we are the best to decide which namespace we want to make the default.

    A simple fix would be to say: If the XML defines a default namespace that is not “android.widgets”, then we will honor it by using version 2 of our XML parser, and all of the standard android widgets would need to be prefixed by something else.

  16. Sergio Trujillo Says:

    And something like this?:

    <?xml version="1.0" encoding="UTF-8"?>
    <android
    xmlns:a="http://schemas.android.com/apk/res/android&quot;
    xmlns:app="com.me.myapp.*">

    <a:LinearLayout
    orientation="vertical"
    layout_width="fill_parent"
    layout_height="fill_parent">

    <app:MyTextView
    layout_width="fill_parent"
    layout_height="wrap_content"
    text="Hello World"
    mySpecialFeature="true"/>

    </a:LinearLayout>

    </android>

Leave a Reply