
Sprint Samsung Galaxy s2 - Activity has leaked IntentReceiver - Are you missing a call to unregister
Question:
I have not seen this error on the Droid Bionic, Droid 3, Motorola Photon 4g, HTC Evo 3d, and the Thunderbolt.
This sample application will throw a "leaked IntentReceiver" error by following these steps:
<ul><li>Somehow aquire a Sprint Samsung Galaxy s2 Epic Touch 4g (the one with the 4.52" screen)</li> <li>Launch application</li> <li>Press "Launch Activity Two" button</li> <li>Open menu, then open the sub menu (Food) - NOTE: You don't need to click on an option, simply viewing the submenu is sufficient</li> <li>Press the phone's back button to close the submenu and menu.</li> <li>Press the phone's back button again to return to ActivityOne - eclipse will print the error below.</li> </ul>If you simply open the menu and select a single option item (not a submenu) then press the back button you will not see the error.
<b>So my question is: Where is this registered IntentReceiver coming from, and how can I unregister it?</b>
Thank you for your time.
# AndroidManifest.xml (Target version is 2.3.3)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".ActivityOne" 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=".ActivityTwo"></activity>
</application>
</manifest>
# one.xml (layout for ActivityOne)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:text="Hello this is activity one" />
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/launch_activity_two"
android:text="Launch Activity Two" />
</LinearLayout>
# two.xml (layout for ActivityTwo)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello this is activity Two. The only way to leave is by pressing the back button on your phone. If you open a submenu (press menu button then select a submenu) - then press the back button on your phone there will be an exception thrown." />
</LinearLayout>
# menu/menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/food" android:title="Food">
<menu>
<item android:id="@+id/food_is_good" android:title="Food is good" />
<item android:id="@+id/food_is_delicious" android:title="Food is delicious" />
<item android:id="@+id/food_is_bad" android:title="Food is bad" />
</menu>
</item>
<item android:id="@+id/doggies_are_cuddly" android:title="Doggies are cuddly" />
</menu>
# ActivityOne
public class ActivityOne extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.one);
// launches activity two
Button button = (Button)findViewById(R.id.launch_activity_two);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), ActivityTwo.class);
startActivity(intent);
}
});
Log.v("Samsung Galaxy sII", "Created Activity One");
}
}
# ActivityTwo
public class ActivityTwo extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.two);
Log.v("Samsung Galaxy sII", "Created Activity Two");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.v("Samsung Galaxy sII", "Creating options menu");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.food_is_bad:
Log.v("Samsung Galaxy sII", "Food is bad");
return true;
case R.id.food_is_good:
Log.v("Samsung Galaxy sII", "Food is good");
return true;
case R.id.food_is_delicious:
Log.v("Samsung Galaxy sII", "Food is delicious");
return true;
case R.id.doggies_are_cuddly:
Log.v("Samsung Galaxy sII", "Doggies are cuddly");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
09-23 00:46:09.210: VERBOSE/Samsung Galaxy sII(28668): Created Activity Two
09-23 00:46:11.791: VERBOSE/Samsung Galaxy sII(28668): Created Activity Two
09-23 00:46:12.705: VERBOSE/Samsung Galaxy sII(28668): Creating options menu
09-23 00:46:19.120: ERROR/ActivityThread(28668): Activity com.test.ActivityTwo has leaked IntentReceiver com.android.internal.view.menu.MenuDialogHelper$1@4052c470 that was originally registered here. Are you missing a call to unregisterReceiver()?
09-23 00:46:19.120: ERROR/ActivityThread(28668): android.app.IntentReceiverLeaked: Activity com.test.ActivityTwo has leaked IntentReceiver com.android.internal.view.menu.MenuDialogHelper$1@4052c470 that was originally registered here. Are you missing a call to unregisterReceiver()?
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:756)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:551)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:858)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.app.ContextImpl.registerReceiver(ContextImpl.java:845)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.app.ContextImpl.registerReceiver(ContextImpl.java:839)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:318)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at com.android.internal.view.menu.MenuDialogHelper.show(MenuDialogHelper.java:97)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at com.android.internal.policy.impl.PhoneWindow.onSubMenuSelected(PhoneWindow.java:808)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:867)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at com.android.internal.view.menu.IconMenuView.invokeItem(IconMenuView.java:532)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at com.android.internal.view.menu.IconMenuItemView.performClick(IconMenuItemView.java:122)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.view.View$PerformClick.run(View.java:9238)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.os.Handler.handleCallback(Handler.java:587)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.os.Handler.dispatchMessage(Handler.java:92)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.os.Looper.loop(Looper.java:130)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at android.app.ActivityThread.main(ActivityThread.java:3691)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at java.lang.reflect.Method.invokeNative(Native Method)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at java.lang.reflect.Method.invoke(Method.java:507)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
09-23 00:46:19.120: ERROR/ActivityThread(28668): at dalvik.system.NativeStart.main(Native Method)
Answer1:onCreateOptionsMenu(Menu menu)
is called every time the options menu is displayed. I did have some strange effects with this too and now use onPrepareOptionsMenu(Menu menu)
instead of this which is just called once for the activity, maybe this helps to get around this issue.
Maybe the Android version installed on S2 calls the method again for the sub menu and somehow leaks a registered IntentReceiver through this, as in this case the menu would get created twice.
Answer2:Check your menu for errors. There are several ways of getting this error on SG2. Often the error is correct even if it's ignored on several devices. Overall, doing something in the menuhandling that causes the normal handling of the menu to end will give you this error. Launching activities from onOptionsItemSelected on items that has submenus for instance.