I'm an Android newbie. I'm writing an app to trace the Activity lifecycle using Log statements. I want to kill my app in order to see the onDestroy() event being called. I've added a button that calls finish to do this, but I've not been able to terminate the app. I've also tried System.exit(0), but my app won't terminate. What am I doing wrong?
public class MainActivity extends Activity {
private static final String LOG_DISPLAY = "DEBUG";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(LOG_DISPLAY, "onCreate called");
}
#Override
protected void onPause() {
super.onPause();
Log.d(LOG_DISPLAY, "onPause called");
}
#Override
protected void onResume() {
super.onResume();
Log.d(LOG_DISPLAY, "onResume called");
}
#Override
protected void onStop() {
super.onStop();
Log.d(LOG_DISPLAY, "onStop called");
}
#Override
protected void onStart() {
super.onStop();
Log.d(LOG_DISPLAY, "onStart called");
}
#Override
protected void onRestart() {
super.onStop();
Log.d(LOG_DISPLAY, "onRestart called");
}
public void addListenerOnButton() {
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
finish();
//System.exit(0);
}
});
}
}
You must override onDestroy in order to check if it is called, and call your addListenerOnButton method too:
Try with this:
public class MainActivity extends Activity {
private static final String LOG_DISPLAY = "DEBUG";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(LOG_DISPLAY, "onCreate called");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_DISPLAY, "onDestroy called");
}
#Override
protected void onPause() {
super.onPause();
Log.d(LOG_DISPLAY, "onPause called");
}
#Override
protected void onResume() {
super.onResume();
Log.d(LOG_DISPLAY, "onResume called");
}
#Override
protected void onStop() {
super.onStop();
Log.d(LOG_DISPLAY, "onStop called");
}
#Override
protected void onStart() {
super.onStop();
Log.d(LOG_DISPLAY, "onStart called");
}
#Override
protected void onRestart() {
super.onStop();
Log.d(LOG_DISPLAY, "onRestart called");
}
public void addListenerOnButton() {
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
MainActivity.this.finish();
//System.exit(0);
}
});
}
}
First add missing onDestroy implementation to show you logs :
#Override
protected void onDestroy() {
Log.d(LOG_DISPLAY, "onDestroy called");
super.onDestroy();
}
Then simply open activity and exit it with hardware back button. You will see onDestroy logs.
You will have same effect calling finish() programmatically as well, just dont forget to place call to your addListenerOnButton somewhere within onCreate
Related
When I run this app I am getting "On Resume" first instead of "On start" even "On create" not showing up, please tell me why? and "On Restart" toast is not displaying but test is getting updated.
public class MainActivity extends AppCompatActivity {
public int test=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast t=Toast.makeText(getApplicationContext(),"On create",Toast.LENGTH_SHORT);
t.setGravity(Gravity.CENTER_VERTICAL,20,20);
t.show();
}
#Override
protected void onRestart() {
super.onRestart();
Toast t=Toast.makeText(getApplicationContext(),"On restart",Toast.LENGTH_LONG);
t.setGravity(Gravity.CENTER_VERTICAL,20,20);
TextView num=(TextView) findViewById(R.id.textNum);
test++;
num.setText(String.valueOf(test));
t.show();
}
#Override
protected void onStart() {
super.onStart();
Toast.makeText(getApplicationContext(),"On start",Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
super.onResume();
Toast t=Toast.makeText(getApplicationContext(),"On resume",Toast.LENGTH_SHORT);
t.setGravity(Gravity.CENTER_VERTICAL,10,20);
t.show();
}
#Override
protected void onPause() {
super.onPause();
Toast t= Toast.makeText(getApplicationContext(),"On Pause",Toast.LENGTH_SHORT);
t.setGravity(Gravity.CENTER_VERTICAL,20,20);
t.show();
}
#Override
protected void onStop() {
super.onStop();
Toast.makeText(getApplicationContext(),"On Stop",Toast.LENGTH_SHORT).show();
}
#Override
protected void onDestroy() {
super.onDestroy();
Toast.makeText(getApplicationContext(),"On destroy",Toast.LENGTH_SHORT).show();
}
}
Using Toast as a debugging method is really bad idea. Use logging and look at your logcat. You will see that the methods get called in the order that they should. Just don't do this.
I have an android studio project. When I am rotating screen, android destroys and recreates main activity. How can I check during the destruction, if android going to recreate activity?
You can determine if the activity is finishing by user choice (user chooses to exit by pressing back for example) using isFinishing() in onDestroy.
#Override
protected void onDestroy() {
super.onDestroy();
if (isFinishing()) {
// wrap stuff up
} else {
//It's an orientation change.
}
}
Another alternative (if you're only targeting API>=11) is isChangingConfigurations.
#Override
protected void onDestroy() {
super.onDestroy();
if (isChangingConfigurations()) {
//It's an orientation change.
}
}
Override the Activity lifecycle methods to see the flow.And then use the appropriate method to check activity current state like isChangingConfigurations()
Example code snippet.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
Log.i(MainActivity.class.getSimpleName(),"OnStart Called");
}
#Override
protected void onRestart() {
super.onRestart();
Log.i(MainActivity.class.getSimpleName(),"OnRestart Called");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.i(MainActivity.class.getSimpleName(),"OnDestroy Called");
}
#Override
protected void onPause() {
super.onPause();
Log.i(MainActivity.class.getSimpleName(),"OnPause Called");
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(MainActivity.class.getSimpleName(),"OnConfiguration Changed Called");
}
}
For more details see the official page activity-lifecycle
///////First Activity///////////
public class MainActivity extends AppCompatActivity
{
Button button;Button button3;MediaPlayer mp2;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
button=(Button)findViewById(R.id.button);
final MediaPlayer mp2 = MediaPlayer.create(this, R.raw.happy);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Intent inent = new Intent(MainActivity.this,
Main2Activity.class);
startActivity(inent);
if(mp2.isPlaying() == true)
{
mp2.pause();}
else{
mp2.start();}
}
});
}
}
/////////Second Activity
public class Main2Activity extends AppCompatActivity
{
Button button2;MediaPlayer mp2;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
}
in your onPause() try this
mp2.stop();
Per the first half of your question: you should get what you want if you call stopMediaPlayer() inside onPause() and onDestroy().
#Override
protected void onPause() {
super.onPause();
stopMediaPlayer();
}
or you can try this too,
#Override
protected void onPause() {
super.onPause();
releaseMediaPlayer();
}
Pause mediaplayer in onStop() and onDestroy() lifecycle methods.
#Override
protected void onStop() {
super.onPause();
mp2.pause();
}
#Override
protected void onDestroy() {
super.onDestroy();
mp2.pause();
}
I have trouble to play music across all activity, I had implement service and handle onPause to stop the music when going to background (not visible to user).
The problem is when i navigate to another activity, the onPause method is called that make my music stop. How to fix this issue? I need to play my music across all my activity in foreground only and dont wan to play it when the application in the background. Appeciate anyone know how to solve this.
This is my base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startIntent = new Intent(getApplicationContext(), MusicService.class);
if(binder==null){
bindService(startIntent,this, Context.BIND_AUTO_CREATE);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(binder.getMyService()!=null){
stopService(startIntent);
unbindService(this);
}
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onPause() {
super.onPause();
if(binder!=null) {
binder.getMyService().pauseMusic();
}
}
#Override
protected void onResume() {
super.onResume();
if(binder!=null){
binder.getMyService().resumeMusic();
}
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MusicService.Binder) service;
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
this is my mainactivity extends base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startIntent = new Intent(MainActivity.this, MusicService.class);
startService(startIntent);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
public void how(View view) {
Intent intent = new Intent(this, AboutActivity.class);
this.startActivity(intent);
}
You could implement code that will track current activity in your app. (Good example: How to get current activity)
And stop music only when "current activity" is null.
PS: depending on your implementation of tracking current activity you might want to check current activity not onPause() right away but with some delay .
Don't stop the audio play in onPause() as Harin Kaklotar suggested. You can use his method of onDestroy() or you can have it in an asynchronous task and turn off the sound by using surfaceDestroyed(). You can refer the android documentation of AudioManager if you need anything else of the sort.
https://developer.android.com/reference/android/media/AudioManager.html
Hope I Helped :D
UPDATE
You can create a system to check if your app is in the foreground or background. This involves counting how many activities are paused. Add this to all your activities:
#Override
protected void onPause() {
super.onPause();
MainActivity.Pause++;
}
#Override
protected void onResume() {
super.onResume();
MainActivity.Pause--;
}
And in your MainActivty,
if (Pause == NUMBER_OF_ACTIVITIES) {
//PAUSE MUSIC HERE
}
You have to use ActivityLifecycleCallbacks to tell if you app is in the foreground or background.
For example:
public class DummyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
#Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { }
#Override public void onActivityStarted(Activity activity) { }
#Override public void onActivityResumed(Activity activity) { }
#Override public void onActivityPaused(Activity activity) { }
#Override public void onActivityStopped(Activity activity) { }
#Override public void onActivityDestroyed(Activity activity) { }
#Override public void onActivitySaveInstanceState(Activity activity, Bundle savedInstanceState) { }
}
public class OnApplicationForegroundBackgroundEnterCallbacks extends DummyActivityLifecycleCallbacks {
private Listener listener;
private int activityStartStopCounter = 0;
public interface Listener {
public void onEnterForeground();
public void onEnterBackground();
}
public OnApplicationForegroundBackgroundEnterCallbacks(Listener listener) {
this.listener = listener;
}
#Override public void onActivityStarted(Activity activity) {
if(++activityStartStopCounter == 1) listener.onEnterForeground();
}
#Override public void onActivityStopped(Activity activity) {
if(--activityStartStopCounter == 0) listener.onEnterBackground();
}
}
Then in Application.onCreate call:
registerActivityLifecycleCallbacks(new OnApplicationForegroundBackgroundEnterCallbacks(this));
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
When I call the startActivity() method to start other activity on the onCreate() method;
Did the other lifecircle method execute,like onStart() or onResume()
I had a test
AppMain.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_main);
Log.i(TAG, "onCreate");
startActivity(new Intent(AppMain.this,AppOther.class));
}
#Override
protected void onRestart() {
Log.i(TAG, "onRestart");
super.onRestart();
}
#Override
protected void onStart() {
Log.i(TAG, "onStart");
super.onStart();
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState");
super.onRestoreInstanceState(savedInstanceState);
}
#Override
protected void onResume() {
Log.i(TAG, "onResume");
super.onResume();
}
#Override
protected void onPause() {
Log.i(TAG, "onPause");
super.onPause();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.i(TAG, "onSaveInstanceState");
super.onSaveInstanceState(outState);
}
#Override
protected void onStop() {
Log.i(TAG, "onStop");
super.onStop();
}
#Override
protected void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
Log.i(TAG, "onConfigurationChanged");
super.onConfigurationChanged(newConfig);
}
AppOther.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_other);
Log.i(TAG, "onCreate");
}
#Override
protected void onRestart() {
Log.i(TAG, "onRestart");
super.onRestart();
}
#Override
protected void onStart() {
Log.i(TAG, "onStart");
super.onStart();
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
Log.i(TAG, "onRestoreInstanceState");
super.onRestoreInstanceState(savedInstanceState);
}
#Override
protected void onResume() {
Log.i(TAG, "onResume");
super.onResume();
}
#Override
protected void onPause() {
Log.i(TAG, "onPause");
super.onPause();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
Log.i(TAG, "onSaveInstanceState");
super.onSaveInstanceState(outState);
}
#Override
protected void onStop() {
Log.i(TAG, "onStop");
super.onStop();
}
#Override
protected void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
Log.i(TAG, "onConfigurationChanged");
super.onConfigurationChanged(newConfig);
}
Logcat:
05-29 05:28:11.583: I/AppMain(1257): onCreate
05-29 05:28:11.614: I/AppMain(1257): onStart
05-29 05:28:11.614: I/AppMain(1257): onResume
05-29 05:28:11.643: I/AppMain(1257): onSaveInstanceState
05-29 05:28:11.643: I/AppMain(1257): onPause
05-29 05:28:11.793: I/AppOther(1257): onCreate
05-29 05:28:11.793: I/AppOther(1257): onStart
05-29 05:28:11.793: I/AppOther(1257): onResume
05-29 05:28:12.383: I/AppMain(1257): onStop
I don't know why the onStart() and onResume() method can still execute;
It's seems that startActivity() did not break the AppMain's lifecycle
Language is pale, speak in code.
Just test it.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v(this.getClass().toString(),"onCreate");
//start other Activity
this.startActivity(new Intent(this,OtherActivity.class));
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.v(this.getClass().toString(),"onDestroy");
}
#Override
protected void onPause() {
super.onPause();
Log.v(this.getClass().toString(),"onPause");
}
#Override
protected void onResume() {
super.onResume();
Log.v(this.getClass().toString(),"onResume");
}
#Override
protected void onStart() {
super.onStart();
Log.v(this.getClass().toString(),"onStart");
}
}
And the logcat shows:
Question's way too narrow but if you start another activity, the current activity will toggle onPause(). and if you finished the called activity the previous activity will toggle onResume(). In short it will not call onResume() and onStart() of current activity if you start another acitivity.