Robotium Activity Leak Causing Wrong Activity for other Tests - android

I am having some issues with my Robotium tests. I have 3 test classes that each have about 2 to 3 methods. They all test different activities in the Android Life Cycle. The problem I am finding is that when test A presses a button in A the intent is called for the next activity the test passes and then finishes. Then test B tries to start an activity. I noticed then that the Activity from test A is still alive. I tried using this to help the problem. The idea would be that the device would wait till the activity was idle then I will end any inactive activities. Then I would end any ones that were open and left.
getInstrumentation().waitForIdleSync();
solo.finishInactiveActivities();
solo.finishOpenedActivities();
I am not sure if this is 100% the best way of taking care of this problem. I have noticed that it works 80% of the time but I am still getting some leaks.

I solved the problem by using the solo.goBack(); function call. This will kill all of the open activities so that there is no leak of activities during your testing. As well I used the code I had placed above as double cover. After repeating these tests on numerous devices and scenarios it seems to pass.

Related

Android Bug after a long time

I have a bug that I am unable to reproduce on command or from the emulator, but seems to happen after leaving the app alone for a long time in the physical device.
All fragments continue to be responsive, but messages seem not to be passed from one fragment to another.
My best guess, is that some sort of garbage collecting might be breaking the links. Very vague question, but I'm desperate:
What could lead to such a bug that happens "after a long time" (ie, hours)? What should I be looking for, in the code I write, if I suspect that the app isn't "restoring" successfully?
Also, adb logcat when physical device is connected via usb debug should show up any error messages that I print with log.e(), correct?
For future googlers and other novice coders -- Today i learned, Save references to fragments you create. Or, don't make fragments local variables. I didn't need the reference to the fragment, only the contained view. As a result, the fragment got garbage collected and a new one recreated on restore, hence breaking the communication link.
Sound like the activity (/fragment) is not save in the memory anymore - Android framework may destroy your activity any time it's in the background or backstack, and you should write your activities so they behave correctly when this happens. In order to beat this override onSaveInstanceState method.
You can cause it happen and try to reproduce it via developer options -> Don't keep activities

Starting singleTask activity every few seconds gives ANR in Android

In the app I have an activity which has launch mode as singleTask. There are number of use cases which pass through this activity and hence it's called number of times. On stress testing the app by running monkeyrunner script and calling this activity every few seconds causes ANR's.
I guess, the way it's designed where most of the use cases pass through this activity is not correct but I am not in a position to change this design.
Is there anyway ANR's can be suppressed? I mean, adding UI operations to event queue so that it doesn't block main UI thread and doesn't give ANR.
It is unclear from the question what your activity is (or should be) doing. Probably you need a service instead.
It is common to perform time-consuming operations in background threads and deliver the results to the UI thread.
You may use the classes Handler/Looper (it it easir to send Runnables rather than messages), or use an AsyncTask. The AsyncTask is nevertheless tricky, this is discussed here: Is AsyncTask really conceptually flawed or am I just missing something? . AFAIK Google tried to fix the typical bugs and made the new behavior incompatible with the old one (namely, I have seen some misbehavior on the newer Androids that may be explained by the assumption that since some version threads doing asynctask jobs get killed after the activity that started them goes out of the screen).
I can guess that singleTask is your way to fight the fact that an activity dies when the screen turns, and a new one comes. I suggest you use singletons (they survive screen rotation but do not survive a process restart, one more thing that sometimes happens in Android). (The user switches to an app like Camera, takes a big photo, returns back -- and the activity is restarted because Camera needed memory. Have seen this in practice, but that time I did not try to find out if the whole process was restarted.)
Anyway, please add logging telling you when your activity in entered and left, including onNewIntent() and other lifecycle functions (to be on the safe side, I recommend to print the thread names as well). Then you will probably see what is going on.

Android app behaving unexpectedly after calling System.exit(0)

I'm writing a simple app with 4 activities. I'll describe it quickly so you understand what I'm trying to achieve.
First activity - MainActivity has some TextEdit fields that collect 2 input parameters - number of reps and length of pause in seconds. A button takes me to the second activity:
WorkActivity - all this does is it starts counting until I press 'done' then it either calls PauseActivity, or if it has been the last rep, calls OverviewActivity.
PauseActivity counts down the seconds until next rep, then beeps at me to let me know it's time, and shows WorkActivity again.
OverviewActivity shows total workout time and times for each rep.
It also features a button that should just end the app. I know exiting your apps is not really in line with the Android application life cycle philosophy, but I need it (or something like it to happen).
I have a singleton controller class that keeps track of the reps and logs the time. I can kill this instance (or fake its death, so a new one will be created), but when I "close" the app and then click it again, I get the OverviewActivity instead of the expected MainActivity.
I expected that calling System.exit(0) would take care of things, simply shut down the application, so it will have to initialize anew when run again. Instead the whole thing started acting really derpy. When I click the button that calls System.exit(0), instead of vanishing my app sort of restarts. It shows the WorkActivity, and starts counting. When I click the done button (which should take me to PauseActivity) I get an exception. The application crashes - and then restarts again. This will repeat until I hit the homescreen button, and the app remains in this useless state until I kill it in application manager.
Also, I'm not exactly sure, but I think the System.exit(0) call (or the subsequent crash) disconnects the debugger, cause I've been unable to get Eclipse to hit any breakpoints afterwards. This means I can't really see the actual exception that occurs.
Can someone shed some light on this? Is there a way to use System.exit(0) correctly?
In the absence of this option, what would be the correct way of handling this?
I need the app to:
- when I click the final 'Done' button the Home button or the Back button, dispose of the Controller, (and everything else if possible), stop counting (if any timer is running) and essentially shut itself down)
- when I click the app's icon again, to show me a new instance (or one that appears new) with the MainActivity to greet me and all other activities in their default state.
Using System.exit(0) is a bad practice.
Calling exit() in this case would terminate the process, killing your
other component and potentially corrupting your data. The OS could
care less of course, but your users might not appreciate it.
Killing voluntarily your process will not help other applications, if
they have exhausted their internal Dalvik heap limit. No matter how
much physical memory a device has, the OS has a limit on how much
memory Dalvik is allowed to use in any process for heap allocations.
Thus, it is possible that the system has free half of its memory and a
particular application still hits OOM.
Do not use System.exit(0); instead you can just use finish().
Intent intent = new Intent(this, Activity2.class);
startActivity(intent);
finish();

keep activity alive after testcase using robotium

Hiii i am testing a test method in which i want after a pressing a button my activity should alive so that i can see next test cases in that activity,but unfortunately my activity get killed after running the test case .is there any way to keep the activity alive.if there code line please let me inform.
I cannot be sure without seeing your code, but i am guessing either in the testcase, or the setup() and tearDown() methods you are going to have to been calling a method such as finishOpenedActivities() which closes all the activities you have open. removing this line will keep the activity open.
Having said that it is typically best practice to have your test cases start from a clean state because having test cases that rely on ordering means that if one fails all the others fail even if that functionality does work plus you have to do slightly hacky things in order to get them to all run in the order you want.
I dug into the source code a bit and found that the tearDown() method, as implemented in ActivityInstrumentationTestCase2, will make a call to finish() on your current activity. So even if you don't explicitly finish() you Activity in your implementation of this method, it will be done when calling super. However, per the source code documentation: removing the call to super in tearDown() can cause a memory leak if you have a non-static inner class, and, perhaps more importantly for your case, the running Activity seems to still be killed once the test is completed. Even if you have an empty implementation of tearDown(), it seems as though the Activity Under Test gets finished at the end of the run. As of right now, I don't know of a way to avoid this.
As an alternative based on your comment for #Paul Harris's answer, Robotium has many methods that allow you to wait for something to happen. You may want to look into waitForText() or waitForView(), which can take a timeout as a argument, to have Robotium pause while your button click is performing some action. Hope this helps!

Android never ShutDown App - Unwanted Behaviour

I know how Android works concerning killing not needed processes if the memory is needed by another app, bu I dont like the following behaviour of the App I develop at the moment:
I start my App, which has a lot of different screens/activities
After using it, i push the Home Button of my phone and switch to some other App.
(Lets say I did this while Activity C on Screen C was active).
My phone is a HTC One X, I checked, that there are always about 300MB of Memory available, when I run the Apps I usually need.
The Problem:
Even if I restart the App after a couple of days without using it, the App restarts with Activity C on screen C. In my opinion, after some days of not using the App, it should restart with the "Welcome Screen" i created.
As there are no Backgroundprocesses or ressources used (all these stuff is done by pushing buttons and has to be finished - so no automated backgroundprocesses are needed), I think, Android does not feel the need to kill it.
Does anybody know, how the "Android Best Practice" looks like for this or where I can read what behaviour the App should have in this case?
(... I am not looking for Code, but I dont know what way I should go to solve this)
Many Thanks for any help
I think you can easily do finish() the activity's on onPause() method.
Not sure whether this is a best practice. Awaiting other answers.
If I'm not mistaking, the following flag can help you when used by an Intent starting a new Activity: FLAG_ACTIVITY_NO_HISTORY. As the documentation says:
f set, the new activity is not kept in the history stack. As soon as the user navigates away from it, the activity is finished.
So if all your Activities, except of the welcome screen, are started using this flag, next time a user comes back to your app he arrives at the welcome screen. The drawback of this solution is that if a user receives a call while working with your application, he will also be transfered to welcome screen when the call is finished. Don't know if there is any other solution. Hope this helps.

Categories

Resources