I seem to be running into a strange problem with an application that has two activities, both of which use mediaplayer:
I am creating an Android game. It has two activities: one for the menu (which launches on start-up) and one for the game (which launches when you select a level).
I have it setup so that if you are in-game and then hit the back-button it returns to the menu activity. Then, ideally, if you hit the back-button again it should exit the application completely. It does not. I placed LogCat debug statements in the menu activity's onPause() and onResume() methods. I can see that onResume() is being called immediately after onPause().
If I disable the music then it exits properly.
Below is my onPause() method for the menu activity. Am I not finishing the mediaplayer properly? Is there anything that would cause onResume() to be called?
GlMainMenu is my GLSurfaceView
protected void onPause() {
GlMainMenu.onPauseCalled = true;
GlMainMenu.mediaPlayer.release();
GlMainMenu.hasPlayedStartMusic = false;
if (isShowingPauseDialog) {
pauseDialog.cancel();
}
super.onPause();
MMglSurfaceView.onPause();
finish();
}
Some notes:
If I launch the app, and press the back-button right away it works fine. It only fails if I launch the app, enter the game, return to the menu, and then try to use the back-button.
using the Home button always exits properly.
In-case it makes any difference, both activities are using opengl for graphics
Related
I am testing my android app that is in development.
It contains a single MainActivity
I noticed through testing that onDestroy was being called every time I push the back button.
I thought that this was weird. So I created a fresh empty activity app using android studio, and added no code. Just a simple hello world.
Even in this hello world app, onDestroy is being called everytime I press back.
I am running a Samsung S4 and I have not reason to believe that it is resource starved. What is going on here?
I tried setting android:launchMode to all available values in AndroidManifest.xml, and none of that worked....
Activity getting destroyed whenever you are pressing back button i.e android default behavior. This is how code flows.
override onBackPressed inside your Activity
/**
* called when user press back button on device
*/
#Override
public void onBackPressed() {
super.onBackPressed();
}
Go inside onBackPressed which lies inside FragmentActivity which shows that it will first pop all fragments from activity and then it will finish activity.
/**
* Take care of popping the fragment back stack or finishing the activity
* as appropriate.
*/
public void onBackPressed() {
if (!mFragments.getSupportFragmentManager().popBackStackImmediate()) {
supportFinishAfterTransition();
}
}
It is normal and expected behavior that OnDestroy() is called after the back button is pressed. This is a standard part of the Android Activity Lifecycle. You can read about the lifecycle here: https://developer.android.com/guide/components/activities/activity-lifecycle.html
I would not recommend overriding the back button behavior as jitesh has suggested unless you have good reason. Users will expect that your app is "closed" (destroyed) once the back button is pressed.
If you want OnDestroy() not being called everytime you tap back button:
#Override
public void onBackPressed() {
// super.onBackPressed(); // remove this line
}
Is there any way to prevent executing code within onResume when returning to an application after the home button has been pressed?
What method is called when the home button is pressed? I could possibly flag something up when home button is pressed?
Thanks
After overriding above method, now you can easily listen HOME Key press in your activity using onKeyDown() method.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_HOME)
{
//The Code Want to Perform.
}
});
Hope this will help
Thanks for the help everyone I managed to solve this by creating a boolean, executeOnResume, which I make false everytime onStop() is called and the app is closed. I then check the state of this boolean in onResume() when the app is opened again to choose whether some code should be executed or not.
onStop()
//-----application stopped
#Override
protected void onStop() {
super.onStop();
//do not execute onResume code when app opened again
executeOnResume = false;
}
onResume()
//-----application resumed
#Override
protected void onResume() {
super.onResume();
//if true
if (executeOnResume) {
//do something
}
else {
//execute onResume true code the next time onResume is called. For example, returning from another activity
}
}
tapping the Home button creates an intent to launch the Home screen and then starts that inten
Correct.
If this is the case, I'd expect the onCreate() method to be run whenever the Home screen is created
Not necessarily. If it is already running, it would be called with onNewIntent().
If someone could just offer some enlightenment into this matter, the basic question is whether onResume() or onCreate() gets called when I tap the Home button
Any time any activity returns to the foreground from a user input standpoint, onResume() is called. Home screens should be no different in this regard.
onCreate() is called when the activity is created. Existing activities are not created, but are merely brought back to the foreground. If what triggered the activity to return to the foreground was a startActivity() call, the activity will be called with onNewIntent() and onResume() (and usually onStart(), for that matter).
Reference : Which method is run when Home button pressed?
Users can leave your app in all kinds of different ways. Pressing HOME is only one of them. An incoming phone call will leave your app, pulling down the list of notifications and pressing one will leave your app, etc. In all of these cases, when the user returns to your app, onResume() will be called. This is standard Android behaviour and tells your app that it is now in the foreground and visible to the user.
Your architecture is flawed if you need to know how the user is returning to your app. You probably need to move some code that you have in onResume() back to onCreate() or onNewIntent().
onCreate() does not get called when I leave the application using back button and start it immediately. I believe this is because, Android has not killed the application process yet. I tried using #AfterViews, the same happens. How could I make sure that every time the application is started, my specific code runs?
Does not get called when I leave the application using back button and then start.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
methodToRun();
}
I use this onBackPressed() to exit the application.
#Override
public void onBackPressed() {
this.moveTaskToBack(true);
this.finish();
}
Even #AfterViews does not get called when I leave the application using back button and then start.
#AfterViews
void checkAgreementFlag(){
methodToRun();
}
I want methodToRun() to always get called. How would I do it?
Call methodToRun() from onResume() of activity.
onResume(): Called when the activity will start interacting with the user. At this point your activity is at the top of the activity stack, with user input going to it.
onCreate(): is called when your application is starting first time.
onRestart(): Called after your activity has been stopped, prior to it being started again.
onStart(): Called when the activity is becoming visible to the user.
onStop() : When the activity is no longer visible.
For the back key scenario activity lifecycle:
onCreate()->onStart()->onResume()->Activity running
After pressing back key
onPause()->onStop()
If the activity is coming back then
onRestart()->onStart()->onResume()->Activity running
otherwise onDestroy() will be called.
A game created by cocos2dx. In active scene, when I touch the back button on android, how can i quit it!
can give same example?
Version cocos2d-2.0-x-2.0.4 and cocos2d-x-2.1.4
in our Layer.h:
...
void keyBackClicked();
...
in our Layer.ccp:
Layer::init(){
...
this->setKeypadEnabled(true);
...
}
void Layer::keyBackClicked() {
CCDirector::sharedDirector()->end();
}
Now you are in a position if you click back then you are navigated to the previous screen where you started off your game application right? Then here is the solution: after navigating to the new intent, the previous screen gets in an inactive state in android activity lifecycle you can find that the previous screen goes to a invisible state. Now we can use onPause() method to close the hidden activity. In the same class add this code and your app should be closed when you press back button.
protected void onPause() {
super.onPause();
finish();
}
When you click any button and go to a new intent the application goes to the invisible state and the onPause() method is triggered automatically and it closes the same intent in background.
Override backKeyClicked() method in your layer.
Don't forget to add this->isKeypadEnabled(true) in init method of layer.
In you backKeyClicked method, you can switch it to previous scene or whatever you wanna do.
I have an activity that is themed as a dialog. I have seen that if the dialog is showing, and then I press the home button, and then using the task manager, restart the app, that dialog activity will be the activity that the app starts in, with no other activities available to go back to. That is, the activity that was running when I loaded the dialog activity is not running. So I just have this dialog-themed activity hovering over the desktop. That makes sense.
Looking over the Android activity lifecycle, the OS does remember the last activity and attempts to restart there. So I created all of the on* methods in my activity (onResume, onRestart, etc). What I found was really puzzling. When I restart the app from the task manager, the following methods are called:
onCreate()
onResume()
onStop()
onDestroy()
Where I was really just expecting
onRestart()
onCreate()
onResume()
Why are onStop and onDestroy getting called right away? And why does the dialog still show, even though onDestroy is called?
How can I configure this app so that it never starts solely on this dialog? I would be fine with the app restarting with the same "parent" activity and the dialog above it (that is, just as I left it), or with just the parent activity running and the dialog dismissed.
In this case, you should use a call to finish() in your Dialog code. You want to do this when the user transitions away from your app (which can happen when they go to the home button, they get a call, etc...). In this case, you would want to make a call to finish() in the onStop() of the Dialog. Calls to finish the current activity remove it from the stack, getting you essentially the behavior you describe.