Ever since I started using one of the newer devices from Google for testing, my tests have gotten stuck whenever we call waitForIdleSync(). When going over the documentation for espresso for another reason, I found this amazing tidbit: "To avoid flakiness, we highly recommend that you turn off system animations". See the main page and how to do it programmatically.
However, I've followed the instructions (disable animations and restart my device) and my tests are still getting stuck. Google's documentation has a habit of getting stale fast, so, is there something else I need to do to get this working on newer devices?
I have the same issue and it broke our tests completely for the last two days.
Problem
I researched this issue a lot. In fact it is an AOSP bug: https://code.google.com/p/android/issues/detail?id=82046
(re-opened from this https://code.google.com/p/android/issues/detail?id=61111)
The problem occurs when you have a a animation, loading spinner, progressbar etc. in your Activity/ Layout that runs for a long time.
waitForIdleSync() will therefore wait forever.
In our case it is very problematic, because the methods getActivity(),launchActivity() and launchActivityWithIntent() of ActivityInstrumentationTestCase2and also the new AndroidTestCase have waitForIdleSync() inside.
Solution Suggestions
You can try turning the animations off or set the Visibility of any ProgressSpinner to GONE via an Intent Flag and start it with that. (Personally, I don't like that solution as it would affect the Activity itself and not the Testcode)
Another way would be to mock the preconditions for the Activity to let it not fall into this state.
Other suggestions are welcome!
Related
Dunno why espresso intermittently can't find a clearly visible elements.
It fails with:
failed: android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: com.justyoyo.staging.debug:id/content_loading_progress_bar
It's freaking frustrating as it doesn't matter whether I'm running the tests on local physical devices, AWS device farm or on Genymotion's emulators. It also doesn't matter that I add an explicit wait SystemClock.sleep(5000); before checking if the element is visible.
I works fine 2,3 times in a row, then it fails.
To give you more insights, we're using Dagger, Mortar and we're running the tests on the UI thread, as running them on separate one was even worse.
I've been having similar issues a lot. I've followed these steps and it has helped a little.
When your test fails with a NoMatchingViewException check the output of the view hierarchy and see if you see the id/text you were searching for. If you find it the view might not be fully visible and you need to scroll to the right position / generally make sure it isn't covered. Even notifications popping down from your status bar can block your view and ruin you test.
If you do not find the view in the view hierarchy try to figure out what layout espresso is actually looking at. I sometimes have dialogs popping up and espresso evaluating that layout instead of the activity that lies below.
Place a breakpoint where your view gets inflated and make sure you actually get there.
But generally difficult to troubleshoot...
Espresso is starting your Activity but is not able to find any view with the id content_loading_progress_bar. This problem does not come from Espresso but from your test.
Make sure your are correctly starting the correct activity. Also regarding to the AWS Device Farm and your tests with Espresso, I suggest you to follow this template. But be careful, to make it work on AWS Device Farm, all your test methods have to start with "testXYZ()" or the farm will not detect them.
I just started to experiment with ads for the first time so I am a complete beginner at this stuff. I have the ads running at the right screens which is good but if you click an ad and it takes you out of the game it causes the game to restart. I made my game in libgdx and I use the pause function and what not but it obviously doesn't call that and in fact just causes a full restart which would make a lot of users angry. Anyone else having this issue or I am doing something wrong?
I am using admob by the way.
EDIT
I also just realized that it happens on my nexus 5 and not my nexus 7.
I think it happened to me some while ago with a game that tried to implement fb sign in functionality. The second it got back from the sign it, it restarted.
What might be happening in your case is that when you click on the add, android switches from your LibGDX activity to the admob activity. Once you come back, the onCreate method gets called again, therefore restarting your app from scratch. (A simple way to verify this is just to add a Log call everytime the app on create method is entered, and check the behaviour of your app)
If that is the case, a possible workaround for it is checking that if your game has been already initialized it should not instantiate it again.
The restart means that your app has crashed. That's standard Android behaviour.
I suspect you have wired something up incorrectly. Look at you log. There's a good chance something hasn't been initialised that should have.
Before reading this, note that I'm not talking about capturing the screen.
Motivation
Many times, in order to test apps, we need to go over many activities (including a loading/splash screen) till we reach the one we've just updated in order to test it out.
I want to reduce this time , by capturing the exact state of the app (memory,preferences,activities stack,...) in order to go there again.
Another example : The QA team could show me in which case a bug occurs, without having to show me the whole process till they got there (since it might not be reproducible) and then I could run the app, and know exactly where the exception was thrown and go there directly via the DDMS's logs .
Another example: We work on a game, and the QA team have tested the game for hours and reached a certain stage, and would like to save the current state of the app in order to test it from this point and make multiple tests on it, instead of running the app from the beginning each time , wait for it to load and also finish all of the stages till they reach this stage.
I think there are other scenarios where such a thing could be useful.
The problem
Such a thing is probably possible in the VM world (for example virualBox) , and it's probably possible for android emulators (at least according to this post , but they also say it's "finicky" , not sure what that means in this context) , but not for devices.
The above example, though they might work, they work for the entire OS and not for a specific app, so even if I choose to use them, it takes a long time to use (plus I need to use an emulator which is usually much slower than any device) .
I'm pretty sure that the current API doesn't support such a thing (and it's probably a good thing, for security reasons).
The question
Is it possible to capture&load entire app state by using ROOT ? Maybe by being a system app too?
Maybe there is already an app for this task?
Since it's very usual that an application saves its whole state in SharedPreferences and persistence in DB, in most apps you can backup and restore data and state using adb backup and adb restore, respectively:
Backup:
adb backup -f app.ab com.company.app
Restore:
adb restore app.ab
PS: This feature was introduced in ICS, and it's not required to be root.
More information in this tutorial.
I have a serious problem with my App continously crashing on some users devices with the following exception in an Activity onStart method:
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1310)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:541)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:525)
at android.support.v4.app.DialogFragment.show(DialogFragment.java:123)
I cannot reproduce this error locally in my emulator. I have found a few questions regarding this issue on stackoverflow:
here and
here
I have tried the suggested solution, i.e. do not allow empty bundles in onSaveInstance neither in fragments nor activities.
However the problem remains. This is the only Crash report I ever get, and I get it continously.
Does anyone have a working solution?
I have solved this issue by
upgrading my support lib to revision 10
using workaround posted here: http://code.google.com/p/android/issues/detail?id=23096
i.e.. Add a non-ui fragment in onResumeFragments and invoke further transactions in Listener Callback.
Check my answer here for code: "Can not perform this action after onSaveInstanceState" - why am I getting this exception from my activity's onResume method?
Got no more IllegalStateException so far.
I solved this using this workaround, namely put the code into a methods onPostResume() function in the Activity
Read This Article.
And,
This one.
Once the issue is understood, go ahead and change things properly:
Figure out why your transactions are happening outside your onResume state. Why are these things happening when they shouldn't be. Why are you manually adding and removing fragments with regard to the lifecycle of you app rather than when the user requests. You should maybe need one time in the onCreate() or when the user invokes something. But why are you messing with them in onResume() in the first place? Don't do that.
If you change all the .commit() to .commitAllowStateLoss() then the crashes will go away. But, you're better off not doing that. You are better off making sure you never change your fragments except when the app is fully live. Sometimes that means never loading a fragment from the OnActivityResult() but rather flagging to run in your onPostResume(), and avoiding performing UI changes in async threads that wrongly assume you couldn't have killed the activity in the meantime.
If you just want to spackle everything, .commitAllowStateLoss() will do that. If you want to do it right, make sure you don't fiddle with your fragments after things die.
One of the more recent forms of Android circa Oreo I think, changed this to avoid this annoying error. My answer seems a bit vague but it's because the bug is in the paradigm. You entirely can hit that with various code elements and fairly routinely.
I am writing an application for Android platform. The application is already almost written for 2.x version, but I want to make it also for Honeycomb version. As you know, Honeycomb has 'Fragments' rather than 'Activities' for tab target.
There is about 30 activities in my application and it must be changed to fragments. It could be very hard word for me, so I want to know the 'best practice' about doing it.
Thanks.
Not really an 100% answer, but just my personal experience so far (and please correct me, anybody, if I got something wrong - I'm still a beginner to Android):
I have the same situation atm and thought I could just re-use my activities and change the layout. E.g. I intended to show my main menu on the left side and all other activities on the right.
However, I soon realized that this isn't really working on Tablet. It just looked crappy and didn't even make sense as the Action bar pretty much replaced my main menu, if used properly. Also, the increased space really screams for a completely different layout. In my app, this will change the user experience completely, so I'll have to re-think the whole app.
On the other hand, stuff that I had to repeat again and again might now be replaced by "invisible" fragments with no UI. I haven't looked closer to this part of the Honeycomb API, but it sounds at least promising.
What I found a nice feature is that you now can "close" your app very easily. In my case I only have one Activity, so a simple "finish" gracefully quits the whole app. I know that this isn't the "Android way" to deal with app life cycle. However, while I don't miss the "close" button on my Android phone (even though some apps, especially games, offer one) I catch myself again and again looking for one on Honeycomb. (That's probably because the GUI reminds one of desktop applications.)
Anyway, long story short: I would recommend re-thinking you app for Tablet. You really have SPACE there, so it just looks strange if you don't use it properly. What this means for your app I don't know - it obviously depends on what kind of app it is. Some activities you'll probably can just use as fragments, some will merge with others, some might become dispensable.
So I guess you should decide first of all if your app really makes sense on Tablets. If not, you could just do the little "optimze" tricks (like applying the holografic theme and maybe new layouts/resources). For everything else I would wait for 4.0/Ice Cream Sandwich, as you will be able to use Fragments on both Smartphone and Tablet then.