NOTE: Activity Flag with android:excludeFromRecents="true"
@Override
protected void onDestroy() {
sendBroadcast(new Intent("com.android.servicerestart"));
if(broadcastReceiver != null) {
try {
unregisterReceiver(broadcastReceiver);
}
catch (IllegalArgumentException E)
{
}
}
super.onDestroy();
Log.e("Activity","In OnDestroy");
}
@Override
protected void onPause() {
if(broadcastReceiver != null) {
try {
unregisterReceiver(broadcastReceiver);
}
catch (IllegalArgumentException E)
{
E.printStackTrace();
}
}
super.onPause();
Log.e("Activity","In OnPause");
}
@Override
protected void onResume() {
registerReceiver();
super.onResume();
Log.e("Activity","In onResume");
}
@Override
protected void onStart() {
super.onStart();
try {
registerReceiver();
}
catch (Exception E)
{
}
}
registerReceiver();
private void registerReceiver() {
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
}
};
try {
registerReceiver(broadcastReceiver, new IntentFilter("*******.receive.service.download"));
}
catch (Exception E)
{
}
}
Logs
E/ActivityThread: Activity **********.activity.MainActivity has leaked IntentReceiver **********.activity.MainActivity$3@3318724 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity **********.activity.MainActivity has leaked IntentReceiver **********.activity.MainActivity$3@3318724 that was originally registered here. Are you missing a call to unregisterReceiver()?
at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:1164)
at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:951)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1308)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1288)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1282)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:586)
at **********.activity.MainActivity.registerReceiver(MainActivity.java:203)
at **********.activity.MainActivity.onStart(MainActivity.java:156)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1255)
at android.app.Activity.performStart(Activity.java:6853)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2712)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2810)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1530)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6256)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:793)
This is a Lifecycle issue
Both start
and resume
register a receiver - but there is no check whether a receiver already exists (so you register two separate receivers)
This means on pause
and destroy
methods can only see the second one and the first is leaked.
The best fix is to remove the start/destroy blocks. Otherwise you may wrap your new BroadcastReceiver
block in if (broadcastReceiver == null)