Recently I stumbled upon a NullPointerException
caused by using findViewById(R.id.whatever)
which returned null
for this id. But the id was in the layout file. And I didn't change the layout programmatically. Furthermore other widgets were found without any problem. Hmm - what's going on?
To analyze the problem I thought about a way to find all views and its ids within my activity. Android makes this a bit more cumbersome than other UI-toolkits, but it's nevertheless possible. First you have to find the root view of your layout and from there you have to go down and iterate over all children of each ViewGroup
present.
But what was happening? Well... The root cause of the problem was that some files had changed and others not and the build did not clean all static references. The ids of the generated files had changed but being static had been inlined. The solution of course was dead simple: A simple recompile of all files solved the problem 🙂
Nevertheless: If you are wondering what is happening in your UI you might want to use this code. You simply have to download the HierarchicalViewIdViewer
and call it's debugViewIds
method, passing in a view you were able to retrieve using findViewById(R.id.whatever)
and a logtag you want to use for logcat
.
The code logs the class names of all widgets and their ids:
V/grokkingandroid( 6427): traversing: TextView, id: 2131034112
V/grokkingandroid( 6427): traversing: LinearLayout, id: -1
V/grokkingandroid( 6427): traversing: LinearLayout, id: -1
V/grokkingandroid( 6427): traversing: ScrollView, id: -1
V/grokkingandroid( 6427): traversing: FrameLayout, id: 16908290
V/grokkingandroid( 6427): traversing: LinearLayout, id: -1
V/grokkingandroid( 6427): traversing: DecorView, id: -1
V/grokkingandroid( 6427): view: LinearLayout(-1)
V/grokkingandroid( 6427): view: ViewStub(16909037)
V/grokkingandroid( 6427): view: FrameLayout(-1)
V/grokkingandroid( 6427): view: TextView(16908310)
V/grokkingandroid( 6427): view: FrameLayout(16908290)
V/grokkingandroid( 6427): view: ScrollView(-1)
V/grokkingandroid( 6427): view: LinearLayout(-1)
V/grokkingandroid( 6427): view: LinearLayout(-1)
V/grokkingandroid( 6427): view: TextView(2131034112)
V/grokkingandroid( 6427): view: LinearLayout(-1)
V/grokkingandroid( 6427): view: Button(-1)
V/grokkingandroid( 6427): view: Button(-1)
As you can see the identation makes it easy to identify hierarchies. Those "traversing" lines at the beginning of the log show you the way from the starting view to the very root of the hierarchy. From there on the method goes downwards and shows you all elements of the hierarchy.
Not all elements have an id value. Those that have none show a "-1" for the id. Others show their id value in hexadezimal. Alas you cannot get the name of the id you used in the xml file. When transferring the xml files to the R file, the Android tools transform them into a unique number and there is no way to get the name from this number.