The next process is simple to understand and to reproduce but leads to a bug:
onCreate()
methodfinish()
in its onResume() methodonDestroy()
is calledonResume()
is calledfinish()
- or press the back key.onDestroy()
is NOT called and A is still living ( adb shell dumpsys 'myPackageName' indicates too many living Activities ) Code
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gleroy.com.algo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".activity.MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="gleroy.com.algo.activity.FakeA"
android:label="@string/app_name"></activity>
<activity
android:name="gleroy.com.algo.activity.FakeB"
android:label="@string/app_name"></activity>
</application>
</manifest>
Activity A :
public class FakeA extends Activity {
private final static String TAG = FakeA.class.getCanonicalName();
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate, taskId :" + getTaskId());
super.onCreate(savedInstanceState);
Intent intent = new Intent(FakeA.this, FakeB.class);
startActivity(intent);
}
@Override
protected void onResume() {
Log.d(TAG, "onResume");
super.onResume();
}
@Override
protected void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.stop_session_menu_item:
/* stop and quit */
finish();
return false;
}
return super.onOptionsItemSelected(item);
}
}
Activity B :
public class FakeB extends Activity {
private final static String TAG = FakeB.class.getCanonicalName();
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate, taskId :"+getTaskId());
super.onCreate(savedInstanceState);
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume, isFinishing :" + isFinishing());
finish();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
}
Activity A is started from MainActivity which contains a simple button :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FakeA.class);
startActivity(intent);
}
});
So I know that we can't be sure that onDestroy()
is gonna be called but here my ActivityA is clearly leaking.
Also I observed that if I use a Timer
and TimerTask
to delay startActivity
in ActivityA or finish()
in ActivityB then I don't have this bug anymore.
Here are the events :
finish() usually triggers a call to onDestroy() . Generally speaking, finish() will eventually result in onDestroy() being called.
Can the system destroy an activity without calling onDestroy? You don't need to call stop( ) method. Android system automatically go thru those life cycle methods.
onDestroy( ) is called before the activity is destroyed. The system invokes this callback either because: the activity is finishing (due to the user completely dismissing the activity or due to finish( ) being called on the activity), or.
onResume() is called whenever you navigate back to the activity from a call or something else. You can override the onResume method similarly as onCreate() and perform the task. This may help you understand the lifecycle of and Android app more.
In place of finish()
try finishAffinity()
.
As far as i know:
finish()
just destroys the current live Activity
while, finishAffinity()
destroys all active Activities
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With