Skip to content

Commit 755c8bf

Browse files
author
Dianne Hackborn
committed
Fix issue #6319312: Consecutive call to Activity's onCreate()/onResume()...
...without onPause() in between There was a bug in the handling of "always finish activities" where we would go through destroying activities while in the middle of updating the activity stack. This would result in the activity behind the non-full-screen activity being created and then immediately destroyed, which things were not expecting. Change-Id: Idaa89089f7b1af7eb747d7b8f9f394beeb2d23fa
1 parent ff0e8cd commit 755c8bf

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

core/java/android/app/ActivityThread.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public final class ActivityThread {
136136
/** @hide */
137137
public static final boolean DEBUG_BROADCAST = false;
138138
private static final boolean DEBUG_RESULTS = false;
139-
private static final boolean DEBUG_BACKUP = true;
139+
private static final boolean DEBUG_BACKUP = false;
140140
private static final boolean DEBUG_CONFIGURATION = false;
141141
private static final boolean DEBUG_SERVICE = false;
142142
private static final boolean DEBUG_MEMORY_TRIM = false;
@@ -1172,10 +1172,10 @@ String codeToString(int code) {
11721172
case DUMP_PROVIDER: return "DUMP_PROVIDER";
11731173
}
11741174
}
1175-
return "(unknown)";
1175+
return Integer.toString(code);
11761176
}
11771177
public void handleMessage(Message msg) {
1178-
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
1178+
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
11791179
switch (msg.what) {
11801180
case LAUNCH_ACTIVITY: {
11811181
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
@@ -1378,7 +1378,7 @@ public void handleMessage(Message msg) {
13781378
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
13791379
break;
13801380
}
1381-
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
1381+
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
13821382
}
13831383

13841384
private void maybeSnapshot() {

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14508,9 +14508,11 @@ final void updateOomAdjLocked() {
1450814508
// activities causes more harm than good.
1450914509
if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
1451014510
&& app != mHomeProcess && app != mPreviousProcess) {
14511+
// Need to do this on its own message because the stack may not
14512+
// be in a consistent state at this point.
1451114513
// For these apps we will also finish their activities
1451214514
// to help them free memory.
14513-
mMainStack.destroyActivitiesLocked(app, false, "trim");
14515+
mMainStack.scheduleDestroyActivities(app, false, "trim");
1451414516
}
1451514517
}
1451614518
}
@@ -14582,7 +14584,9 @@ final void updateOomAdjLocked() {
1458214584
}
1458314585

1458414586
if (mAlwaysFinishActivities) {
14585-
mMainStack.destroyActivitiesLocked(null, false, "always-finish");
14587+
// Need to do this on its own message because the stack may not
14588+
// be in a consistent state at this point.
14589+
mMainStack.scheduleDestroyActivities(null, false, "always-finish");
1458614590
}
1458714591
}
1458814592

services/java/com/android/server/am/ActivityStack.java

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import android.content.res.Configuration;
4646
import android.content.res.Resources;
4747
import android.graphics.Bitmap;
48-
import android.net.Uri;
4948
import android.os.Binder;
5049
import android.os.Bundle;
5150
import android.os.Handler;
@@ -289,7 +288,19 @@ enum ActivityState {
289288
static final int RESUME_TOP_ACTIVITY_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
290289
static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 7;
291290
static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 8;
292-
291+
static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 9;
292+
293+
static class ScheduleDestroyArgs {
294+
final ProcessRecord mOwner;
295+
final boolean mOomAdj;
296+
final String mReason;
297+
ScheduleDestroyArgs(ProcessRecord owner, boolean oomAdj, String reason) {
298+
mOwner = owner;
299+
mOomAdj = oomAdj;
300+
mReason = reason;
301+
}
302+
}
303+
293304
final Handler mHandler = new Handler() {
294305
//public Handler() {
295306
// if (localLOGV) Slog.v(TAG, "Handler started!");
@@ -384,6 +395,12 @@ public void handleMessage(Message msg) {
384395
}
385396
}
386397
} break;
398+
case DESTROY_ACTIVITIES_MSG: {
399+
ScheduleDestroyArgs args = (ScheduleDestroyArgs)msg.obj;
400+
synchronized (mService) {
401+
destroyActivitiesLocked(args.mOwner, args.mOomAdj, args.mReason);
402+
}
403+
}
387404
}
388405
}
389406
};
@@ -3821,19 +3838,39 @@ final void cleanUpActivityServicesLocked(ActivityRecord r) {
38213838
r.connections = null;
38223839
}
38233840
}
3824-
3841+
3842+
final void scheduleDestroyActivities(ProcessRecord owner, boolean oomAdj, String reason) {
3843+
Message msg = mHandler.obtainMessage(DESTROY_ACTIVITIES_MSG);
3844+
msg.obj = new ScheduleDestroyArgs(owner, oomAdj, reason);
3845+
mHandler.sendMessage(msg);
3846+
}
3847+
38253848
final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String reason) {
3849+
boolean lastIsOpaque = false;
38263850
for (int i=mHistory.size()-1; i>=0; i--) {
38273851
ActivityRecord r = mHistory.get(i);
3852+
if (r.finishing) {
3853+
continue;
3854+
}
3855+
if (r.fullscreen) {
3856+
lastIsOpaque = true;
3857+
}
38283858
if (owner != null && r.app != owner) {
38293859
continue;
38303860
}
3861+
if (!lastIsOpaque) {
3862+
continue;
3863+
}
38313864
// We can destroy this one if we have its icicle saved and
38323865
// it is not in the process of pausing/stopping/finishing.
3833-
if (r.app != null && r.haveState && !r.visible && r.stopped && !r.finishing
3866+
if (r.app != null && r != mResumedActivity && r != mPausingActivity
3867+
&& r.haveState && !r.visible && r.stopped
38343868
&& r.state != ActivityState.DESTROYING
38353869
&& r.state != ActivityState.DESTROYED) {
3836-
destroyActivityLocked(r, true, oomAdj, "trim");
3870+
if (DEBUG_SWITCH) Slog.v(TAG, "Destroying " + r + " in state " + r.state
3871+
+ " resumed=" + mResumedActivity
3872+
+ " pausing=" + mPausingActivity);
3873+
destroyActivityLocked(r, true, oomAdj, reason);
38373874
}
38383875
}
38393876
}
@@ -3847,7 +3884,7 @@ final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String r
38473884
final boolean destroyActivityLocked(ActivityRecord r,
38483885
boolean removeFromApp, boolean oomAdj, String reason) {
38493886
if (DEBUG_SWITCH) Slog.v(
3850-
TAG, "Removing activity: token=" + r
3887+
TAG, "Removing activity from " + reason + ": token=" + r
38513888
+ ", app=" + (r.app != null ? r.app.processName : "(null)"));
38523889
EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
38533890
System.identityHashCode(r),

0 commit comments

Comments
 (0)