diff options
author | Johannes Carlsson <johannes.carlsson.x@sonyericsson.com> | 2010-10-27 10:08:10 +0200 |
---|---|---|
committer | Steve Kondik <shade@chemlab.org> | 2010-11-21 04:22:50 -0500 |
commit | 78a97b98a8e53c9b1b808f6011b86621f4918bfe (patch) | |
tree | fdebf640c77e996584df75eaea0055608eb580f9 | |
parent | fb435619ead394bcb7188143cb49a673ce5c1477 (diff) | |
download | frameworks_base-78a97b98a8e53c9b1b808f6011b86621f4918bfe.zip frameworks_base-78a97b98a8e53c9b1b808f6011b86621f4918bfe.tar.gz frameworks_base-78a97b98a8e53c9b1b808f6011b86621f4918bfe.tar.bz2 |
Clear reference to the IIntentReceiver in order to avoid memory leak
When using sendOrderedBroadcast(..) with a BroadcastReceiver the
BroadcastReceiver instance was not released. The reason for this was that
the resultTo field in the BroadcastRecord kept a reference until it was pushed
out of the mBroadcastHistory. This reference in turn kept a reference to the
process side IIntentReceiver (implemented in ReceiverDispatcher$InnerReceiver).
This in turn had a strong reference (through mStrongRef) to the Context.
In order to keep the debug output the resultTo is also kept as a String in the
new resultToString variable.
Change-Id: I4382a22a541c27b3694fb2b78a04ee820b235f8f
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 3 | ||||
-rw-r--r-- | services/java/com/android/server/am/BroadcastRecord.java | 8 |
2 files changed, 8 insertions, 3 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 0aebc1c..837011e 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -13199,6 +13199,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen performReceive(r.callerApp, r.resultTo, new Intent(r.intent), r.resultCode, r.resultData, r.resultExtras, false, false); + // Set this to null so that the reference + // (local and remote) isnt kept in the mBroadcastHistory. + r.resultTo = null; } catch (RemoteException e) { Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e); } diff --git a/services/java/com/android/server/am/BroadcastRecord.java b/services/java/com/android/server/am/BroadcastRecord.java index c3f0b3e..4faaeca 100644 --- a/services/java/com/android/server/am/BroadcastRecord.java +++ b/services/java/com/android/server/am/BroadcastRecord.java @@ -44,7 +44,8 @@ class BroadcastRecord extends Binder { final boolean initialSticky; // initial broadcast from register to sticky? final String requiredPermission; // a permission the caller has required final List receivers; // contains BroadcastFilter and ResolveInfo - final IIntentReceiver resultTo; // who receives final result if non-null + IIntentReceiver resultTo; // who receives final result if non-null + private final String resultToString; // resultTo.toString() used for debug purposes long dispatchTime; // when dispatch started on this set of receivers long receiverTime; // when current receiver started for timeouts. long finishTime; // when we finished the broadcast. @@ -100,8 +101,8 @@ class BroadcastRecord extends Binder { if (anrCount != 0) { pw.println(prefix + "anrCount=" + anrCount); } - if (resultTo != null || resultCode != -1 || resultData != null) { - pw.println(prefix + "resultTo=" + resultTo + if (resultToString != null || resultCode != -1 || resultData != null) { + pw.println(prefix + "resultTo=" + resultToString + " resultCode=" + resultCode + " resultData=" + resultData); } if (resultExtras != null) { @@ -164,6 +165,7 @@ class BroadcastRecord extends Binder { requiredPermission = _requiredPermission; receivers = _receivers; resultTo = _resultTo; + resultToString = resultTo == null ? null : resultTo.toString(); resultCode = _resultCode; resultData = _resultData; resultExtras = _resultExtras; |