Instrumentation test doesn't match view ids from hierarchy - android

In short, I'm trying to match view with ID like R.id.signCheckbox using Espresso. When I try to match that view I will get NoMatchingView exception when it's clear that view is present.
After some debugging, I've found out that inside my test class when I eval R.id.signCheckbox I'll get ID: -1000984. Inside cause of the NoMatchingViewException you can actually read whole view hierarchy in some format. There I've found that checkbox has different ID 2131362821. I've read the project R.java and it's also assigning 2131362821 to R.id.signCheckbox.
So when I match withId(2131362821) it's actually working. Why it's not working with R.id.signCheckbox and where that -1000984 id comes from?

It looks like the good old Invalidate/Restart/Clean/Rebuild fixed the problem.
The IDs are still negative (like -1000984) not matching the R.java IDs, but Espresso will successfully match the views.

Related

How does findViewById() method work in activity?

When I add a view to xml (layout) of my activity, it takes an id, so I can use that id in code of activity to recognize it and change my view if I like. Android make an R.class as an intermediate between my activity code an my layout(xml), so I use R.class for example:
findViewById(R.id.textView);
But how does android find it is a TextView? For example, if I write:
Button b = findViewById(R.id.textView);
I get an error. From where does it find I write it wrong?
I mean in R.class it define my id so android know a new id is defined in my xml, and I use it to return an object of View class or class extend View. But how does it find I am writing wrong and it is not a button, before I run the program (in compile time)?
Android Studio runs Android lint checks on your code, and there's the WrongViewCast check to detect such issues and report them as errors:
WrongViewCast
-------------
Summary: Mismatched view type
Priority: 9 / 10
Severity: Error
Category: Correctness
Keeps track of the view types associated with ids and if it finds a usage of
the id in the Java code it ensures that it is treated as the same type.
Source: http://tools.android.com/tips/lint-checks
If your view, that is returned by findViewById(R.id.ID), doesn't cast to the field you're assigning the view to, your code won't even compile! Android Studio checks your assigned variables and tries to cast them in real-time, but if that fails, because you made a mistake, your Activity.java can't compile! This is just a way of how this IDE operates.
Some time ago, you needed to cast the view manually, like this:
(TextView) findViewById(R.id.text_view)
But this is not necessary anymore.

Espresso verify if text does not exist not working

I want to verify that a string retrieved from a DB entry is not present anymore after the entry in DB changed, I am using following statement for this:
onView(allOf(withText("oldname"), withId(R.id.title))).check(doesNotExist());
According to the espresso documentation and other posts I saw this should work, but I am getting following error:
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: (with text: is "oldname" and with id: com.myco.myapp:id/apkName)
The problem is that you're looking for a View with the text "oldname" and then trying to assert that it doesn't exist, but this doesn't work because the View doesn't exist (so you can't assert anything on it).
Where you go from here depends on exactly what you're trying to accomplish. If the view should not be there at all:
onView(withId(R.id.title)).check(doesNotExist());
If the view should be there, but without that text:
onView(allOf(not(withText("oldname")),withId(R.id.title))).check(matches(isDisplayed());
Or a variation of that:
onView(withId(R.id.title)).check(matches(not(withText("oldName"))));
The first variation says "make sure that there's a view with that id and not that text". The second variation says "make sure that the view with that id doesn't have that text".

Android same name issue

I'm creating my first android app and i have a few layouts so far. In one of them i created a TextView and named it "textViewCurrentUserName". For my surprise, when i created a new layout, inserted a new TextView and try to name it "textViewCurrentUserName" i got a error stating that the name already exists!!! This has got to be a bug right?!? i mean, ok to "no repeat" on the same layout (xml), but these are totally different layouts!!!
Am I doing something wrong here?!? Is there a workaround this??? i dont want to keep a totally idiotic and hard-to-read/understand name such as "activity_UserDetails_TextViewCurrentUserName" and "activity_UserExport_TextViewCurrentUserName"
The Android ID field creates a unique ID for each UI element and stores them in the R file. Since fragments/activities and layouts and fairly decoupled, the app itself won't know which layouts and UI elements are available. Thus, you must explicitly state which element you're looking for. The app will throw an exception if the specified UI element is not currently available (or, perhaps, the element will be null).
The only workaround is to develop a naming convention. One might use [fragment-name]_textViewCurrentUser to allow each text view to have a unique ID. Or perhaps you can put a lowercase "t" in front of each UI element that is a text view: [fragment-name]_tCurrentUser.

How to find a code behind a view in hierarchyviewer

Android hierarchyviewer shows a ID for each view in the tree view.
The ID is a # sign followed by a number, e.g #4051d698
In android documentation the purpose of this number is explained as "pointer to view object".
Assuming one has the sources of a very big android project like AOSP.
How can one figure out what is the java source code behind the view by using this ID?
Is there a method I can invoke that tells me what is the R.java entry that is bound to this pointer?
How can one figure out what is the java source code behind the view by using this ID?
You can't, at least without a debugger. If you are used to C/C++ development, that hexadecimal value is roughly analogous to a pointer. Just because you have a pointer to a hunk of RAM in C/C++ does not mean that you can determine the source code behind the object resident at that pointer.
Now, it is possible that there is a way in a debugger to supply this hex value and the debugger will match that up to an object and source code. I am not an Eclipse expert, or an expert on another other IDE debuggers, to know whether or not there is a means to do this. However, even if can do this, it will probably only give you the source of the class of the object (e.g., if the View is a ListView, it might send you to the ListView source code), not the source code of what created the object.
Is there a method I can invoke that tells me what is the R.java entry that is bound to this pointer?
First, R.java is not "bound" to any pointers.
Second, the View in question may not have come from an inflated layout. It might have been created directly in Java code instead.
If the View has an "View object ID" (e.g., id/content), that can better help you find where it came from, as that will be an android:id value, possibly from your layout resources.

How to access a View by an ID of the android namespace

In hierarchy viewer there are several IDs as shown above, for example "id/timepicker_input".
But I can't find a respective timepicker_input - ID when typing
myNumberPicker.findViewById(android.R.id. ...? );
So how to access these Views by their ID?
Make shure there is no import android.R... defined and build your project after altering your layouts.

Categories

Resources