I found some CTS errors which are given below:
Compatibility Test Case: CtsAppTestCases
Package Name: android.app.cts.DialogTest
Error:
-- testContextMenu fail junit.framework.AssertionFailedError
at android.app.cts.DialogTest.testContextMenu(DialogTest.java:971)`
-- testTabScreen fail java.lang.RuntimeException: Intent {
act=Activity lifecycle incorrect: received
onResume but expected onStop at 5 }
at android.app.cts.ActivityTestsBase.waitForResultOrThrow(ActivityTestsBase.java:149)
-- testTabScreen fail java.lang.RuntimeException: Intent {
act=Activity lifecycle incorrect: received
onResume but expected onStop at 5 }
at android.app.cts.ActivityTestsBase.waitForResultOrThrow(ActivityTestsBase.java:149)
-- testScreen fail java.lang.RuntimeException: Intent { act=Activity
lifecycle incorrect: received onResume but expected onStop
at 5 }
at android.app.cts.ActivityTestsBase.waitForResultOrThrow(ActivityTestsBase.java:149)`
This Test is expecting the lifecycle as onPause() then onStop(), but onResme() was called rather than onStop().
According to Android Activity Docs – “After receiving this call you will usually receive a following call to onStop() (after the next activity has been resumed and displayed), however in some cases there will be a direct call back to onResume() without going through the stopped state.”
So, it is not mandatory to get desired sequence.
Related
I found my activities onStop() method will be called with a less than 10 seconds delay. I've never seen before this behavior.
Note :- The activity is singleTop and it starts with Intent.FLAG_ACTIVITY_REORDER_TO_FRONT flag.
Note :- I'm using Build Tools v23.0.2.
The delay wasn't before and the method would be called immediately.
I am guessing that you are starting another activity and you expect the current activity to receive an onStop() callback. According to the activity lifecycle, the onPause() method is called before the onStop(). In some cases onSaveInstance() is also called before the onStop() method. Additionally, when you call the startActivity or the startActivityForResult (again, I am assuming that is why you expect the onStop to be called), depending on the parameters that are passed, if those parameters need to be calculated/fetched/etc, it may take a while before the system can execute the startActivity, which would be the earliest that Android would initiate the life cycle calls. In the absence of any code here, it is not possible to see what else is getting executed before the onStop is called. I suggest you check the timeline for the code execution time, starting with the startActivity and when onStop is called, maybe by logging the timestamps for each call, starting with the timestamp just before the startActivity call, ending in the timestamp at the start of the onStop, to see where time is spent. I also suggest to simplify this by making sure that all parameters to the startActivity or startActivityForResult are previously set to their values, if that is not already the case.
You can fix the problem by either adding noHistory:true to the activity in the manifest file or by setting the flag programmatically. I had the same problem and this fixed it for me.
In my case, I stop video player when onStop() invoked, but the onStop() invoke has a 10s delay.
You can use something like eventBus, RxBus to post a event in the
Application.ActivityLifecycleCallbacks {
//post event here.and check the activity's Name in my targetActivity which play my video.
onActivityStarted()
}
I had the same problem. When I started an activity with startActivity(), onStop() was called exactly 10 seconds after onPause().
In my case, the activity being launched had a fragment, which had a WebView. I have no idea why, but if I removed following line, the delay was only around 2 seconds.
webView.setScrollbarFadingEnabled(false);
I have just faced this issues, after debugging there is a case that AdView (Admob banner) causes this issue.
In activity A (which is placed an adview) i start activity B. Back to A from B and onPause of B call immediately but all stop/destroy take 10s to be called. Remove the ad banner then everything get back normal.
Just post this case here for anyone to ref.
May be emulator is slow today
but onStop() should be called at once as single command
no onPause() or anything is called before this
I'm using Android on Xamarin, if this is relevant. Consider the following situation:
Activity A's OnCreate() executes and an error is encountered
Activity A spawns Activity B (an error message dialog) and OnCreate() returns
Activity B is dismissed
Activity A's OnActivityResult executes, where finish() is called
In this situation on Xamarin, sometimes OnCreate/OnResume of Activity A will have time to execute before Activity A is finished. For instance, this can happen if a configuration change occurred when Activity B was in the foreground. This can result in the error message dialog being displayed more than once, which is not desired.
This is easily alleviated by querying isFinishing() before displaying the error message in Activity A. But I'm thinking that this behavior can cause more subtle bugs, e.g. if OnCreate/OnResume have side effects that change global state in the app.
Is there a good reason not to do
if (isFinishing()) { return; }
at the start of every activity's OnCreate, OnRestart and OnResume?
I'm trying to write an Android activity instrumentation test that stops (onPause(), then onStop()) and restarts the current activity. I tried
activity.finish();
activity = getActivity();
...but that doesn't seem to work properly.
The goal of the test is to assert that form data is stored during the onPause() method and re-read during the onStart() method. It works when doing it manually, but the test fails, from which I draw the conclusion that activity.finish() seems to be the wrong way to stop and restart an activity.
Edit: My main problem seems to have been a synchronization issue. After restarting the activity, the test runner didn't wait for all event handlers to finish. The following line halts the test execution until the activity is idle:
getInstrumentation().waitForIdleSync()
Besides that, take a look at the accepted answer for more valuable information about the lifecycle.
By calling (or trigger a screen orientation change):
activity.finish(); // old activity instance is destroyed and shut down.
activity = getActivity(); // new activity instance is launched and created.
Causing the activity go through the complete recreation life cycle:
onPause() -> onStop() -> onDestroy() -> onCreate()
What you need is:
onPause() -> onStop() -> onRestart()
I exposed the Instrumentation API recently and found plenty of interesting activity life cycle trigger method callActivityOnXXX(), the following single line of code should do the tricky:
MyActivity myActivity = getActivity();
// make activity falling into restart phase:
getInstrumentation().callActivityOnRestart(myActivity);
Activity life cycle diagram quoting from official dev guide:
I tried calling .finish(), setActivity(null), getActivity() and it does restart the activity, but for me it was not restoring the state. I tried out all the other answers on SO, and every other method to do this I could find online, and none of them worked for me. After much experimentation I found the following works (nb: requires API level 11+):
getInstrumentation().runOnMainSync(new Runnable() {
#Override
public void run() {
activity.recreate();
}
});
setActivity(null);
activity = getActivity();
When I do this a new Activity instance is created, and a new instance of the fragment I had attached to the activity earlier in the test is also created, and both the activity and fragment restore their state in the expected manner.
I don't know how this works or why this works, I reached this solution through trial and error, and I have only tested it on a Nexus 4 running KitKat. I can't guarantee it correctly simulates an activity recreation, but it worked for my purposes.
Edit: At a later date I figured out how this works. getActivity() works through registering hooks that receive new Activities being created, which catch the new Activity created by activity.recreate(). setActivity(null) was required to clear the internal cache backing getActivity, otherwise it will return the old one and not look for a new one.
You can see how this works from examining the source code for the various test case classes one extends from.
A good way to test lifecycle events is through screen orientation changes. In my experience it's a convenient way to bombproof the onPause / onStart pattern.
Maybe u could try to save the name of your activity,
finish it... and use reflection to get a new instance of the .class for the new intent to create...
Change your code as follows:
mActivity.finish();
setActivity(null);
mActivity = this.getActivity();
A full explanation can be found in this question
ActivityScenario.recreate() seems to work fine. I don't think the other complex solutions are needed anymore.
Given this test
#Test
fun activity_is_recreated() {
activityScenario = ActivityScenario.launch(TestingLifecycleActivity::class.java)
activityScenario.onActivity {
Timber.d("inside onActivity $it")
//do assertions
}
Timber.d("pre recreate")
activityScenario.recreate()
Timber.d("post recreate")
activityScenario.onActivity {
Timber.d("inside onActivity $it")
//do assertions
}
}
These are the lifecycle related logs
Lifecycle status change: TestingLifecycleActivity#e34cfb7 in: PRE_ON_CREATE
Lifecycle status change: TestingLifecycleActivity#e34cfb7 in: CREATED
Lifecycle status change: TestingLifecycleActivity#e34cfb7 in: STARTED
Lifecycle status change: TestingLifecycleActivity#e34cfb7 in: RESUMED
inside onActivity TestingLifecycleActivity#e34cfb7
pre recreate
Schedule relaunch activity: TestingLifecycleActivity
Lifecycle status change: TestingLifecycleActivity#e34cfb7 in: PAUSED
Lifecycle status change: TestingLifecycleActivity#e34cfb7 in: STOPPED
Lifecycle status change: TestingLifecycleActivity#e34cfb7 in: DESTROYED
//new activity instance is launched
Lifecycle status change: TestingLifecycleActivity#ac46813 in: PRE_ON_CREATE
Lifecycle status change: TestingLifecycleActivity#ac46813 in: CREATED
Lifecycle status change: TestingLifecycleActivity#ac46813 in: STARTED
Lifecycle status change: TestingLifecycleActivity#ac46813 in: RESUMED
post recreate
inside onActivity TestingLifecycleActivity#ac46813
Finishing activity: TestingLifecycleActivity#ac46813
I have an activity that is triggered by a notification (when the user clicks).
1) When there is no other activity (from my app) alive, the activity does not rotate when the orientation changes. OnCreate() does not get called
2) When another activity is running (below), then when I rotate the device onCreate() gets called once but the activity dies immediately. No error logged
I can't see anything special in my activity but the fact that it is triggered by a notification and that it has a broadcast receiver in it (private class).
Thank you for your thoughts
EDIT: Please discard this question. I had a finish() in onStop().
Add a log statement in the Activity.onCreate() method that is dying. More likely is your activity is being recreated and something is tossing an exception. If you see the onCreate() statement in the logs twice then you know you likely having an exception being thrown. Even without it you can trace down which line its dying on by adding more log statements.
On orientation changes you're activity will be torn down and rebuilt unless you fixed the orientation in the manifest. If a service or broadcast receiver has a reference to it after it's torn down then any call to it will likely cause it to die as you're seeing. This is where Android's lifecycle is more hassle than its worth, but it is what it is.
More than likely something is throwing an exception and you're not seeing it or its being masked by another one being thrown. Make sure you're not filtering your logcat output by tag.
I understand that if my app is already running and I haven't made any code changes, LogCat displays the following warning:
ActivityManager: Warning: Activity not
started, its current task has been
brought to the front
What I don't understand is why no activity lifecycle like onResume() or onRestart() is called.
The app was not visible before I tried to re-run it, so why no onResume() or onRestart() callback was called?
Are you sure onResume() is not called? In all of my code I see onResume being called. Perhaps a sample code post showing the contrary.