Last active
June 11, 2020 18:15
-
-
Save curioustechizen/8728945 to your computer and use it in GitHub Desktop.
Tiny utility class that helps avoid book-keeping code when dealing with registering and unregistering BroadcastReceivers. Hopefully, this will help you get rid of "Activity has leaked IntentReceiver that was originally registered here" messages without resorting to using boolean flags to keep track of your BroadcastReceivers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.curioustechizen.safereg; | |
import android.content.BroadcastReceiver; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.content.IntentFilter; | |
import android.support.v4.util.ArrayMap; | |
/** | |
* Helper class to keep track of what {@code BroadcastReceiver}s have been | |
* registered for this context. Requests for registering a new receiver will act | |
* only if the not already registered. Similarly, requests for unregistering a | |
* receiver will act only if the register is already registered. | |
* | |
* @author Kiran Rao | |
* | |
*/ | |
public class ReceiverRegistrar { | |
private Context mContext; | |
private ArrayMap<BroadcastReceiver, Intent> mReceiverMap; | |
/** | |
* Construct a new instance of the registrar. | |
* | |
* @param context | |
* The context that is used for registering the receiver | |
*/ | |
public ReceiverRegistrar(Context context) { | |
mContext = context; | |
mReceiverMap = new ArrayMap<BroadcastReceiver, Intent>(); | |
} | |
/** | |
* Register a {@code BroadcastReceiver}. If the receiver is already | |
* registered then this method will simply return the {@code Intent} | |
* returned by the previous {@code registerReceiver} call. | |
* | |
* @see {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)} | |
* @param receiver | |
* The BroadcastReceiver to handle the broadcast | |
* @param filter | |
* The filter to select the broadcasts to be handled | |
* @return The first sticky intent found that matches filter, or null if | |
* there are none. If this receiver has already been registered, | |
* then the return value is the intent that was returned when the | |
* receiver was originally registered. | |
*/ | |
public Intent safeRegisterReceiver(BroadcastReceiver receiver, | |
IntentFilter filter) { | |
if (!mReceiverMap.containsKey(receiver)) { | |
Intent intent = mContext.registerReceiver(receiver, filter); | |
mReceiverMap.put(receiver, intent); | |
return intent; | |
} else { | |
return mReceiverMap.get(receiver); | |
} | |
} | |
/** | |
* Unregister a {@code BroadcastReceiver}, if it hasn't been registered | |
* already. | |
* | |
* @param receiver | |
*/ | |
public void safeUnregisterReceiver(BroadcastReceiver receiver) { | |
if (mReceiverMap.containsKey(receiver)) { | |
mContext.unregisterReceiver(receiver); | |
mReceiverMap.remove(receiver); | |
} | |
} | |
/** | |
* Unregister all {@code BroadcastReceiver}s registered with this context. | |
*/ | |
public void safeUnregisterAllReceivers() { | |
for (BroadcastReceiver receiver : mReceiverMap.keySet()) { | |
safeUnregisterReceiver(receiver); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.curioustechizen.safereg; | |
import android.app.Activity; | |
import android.content.BroadcastReceiver; | |
import android.content.IntentFilter; | |
import android.os.Bundle; | |
/* | |
* Naive implementation of registering and un-registering multiple BroadcastReceivers | |
* in an Activity using boolean flags to keep track of whether they have been registered. | |
* | |
* You probably want to use ReceiverRegistrar instead of this as demonstrated in SampleRecommendedActivity.java | |
*/ | |
public class SampleNaiveActivity extends Activity { | |
private BroadcastReceiver mConnectivityReceiver, mBatteryReceiver; | |
private IntentFilter mConnectivityFilter, mBatteryFilter; | |
private boolean mRegisteredConnectivityReceiver, | |
mRegisteredBatteryReceiver; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
/* | |
* Initialize the BroadcastReceivers here Setup the IntentFilters here | |
*/ | |
} | |
@Override | |
protected void onResume() { | |
super.onResume(); | |
/* | |
* Register your receivers in onResume | |
*/ | |
registerBatteryReceiver(); | |
registerConnectivityReceiver(); | |
} | |
private void onBatteryLow() { | |
/* | |
* Maybe when the battery goes low you want to unregister a few | |
* receivers? | |
*/ | |
unregisterConnectivityReceiver(); | |
} | |
@Override | |
protected void onPause() { | |
super.onPause(); | |
/* | |
* In onPause, unregister all remaining registered receivers | |
*/ | |
unregisterBatteryReceiver(); | |
unregisterConnectivityReceiver(); | |
} | |
private void registerBatteryReceiver() { | |
if (!mRegisteredBatteryReceiver) { | |
mRegisteredBatteryReceiver = true; | |
registerReceiver(mBatteryReceiver, mBatteryFilter); | |
} | |
} | |
private void unregisterBatteryReceiver() { | |
if (mRegisteredBatteryReceiver) { | |
mRegisteredBatteryReceiver = false; | |
unregisterReceiver(mBatteryReceiver); | |
} | |
} | |
private void registerConnectivityReceiver() { | |
if (!mRegisteredConnectivityReceiver) { | |
mRegisteredConnectivityReceiver = true; | |
registerReceiver(mConnectivityReceiver, mConnectivityFilter); | |
} | |
} | |
private void unregisterConnectivityReceiver() { | |
if (mRegisteredConnectivityReceiver) { | |
mRegisteredConnectivityReceiver = false; | |
unregisterReceiver(mConnectivityReceiver); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.github.curioustechizen.safereg; | |
import android.app.Activity; | |
import android.content.BroadcastReceiver; | |
import android.content.IntentFilter; | |
import android.os.Bundle; | |
public class SampleRecommendedActivity extends Activity { | |
private BroadcastReceiver mConnectivityReceiver, mBatteryReceiver; | |
private IntentFilter mConnectivityFilter, mBatteryFilter; | |
private ReceiverRegistrar mReceiverRegistrar; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
/* | |
* Initialize the BroadcastReceivers here and Setup the IntentFilters here | |
*/ | |
mReceiverRegistrar = new ReceiverRegistrar(this); | |
} | |
@Override | |
protected void onResume() { | |
super.onResume(); | |
/* | |
* Register your receivers in onResume | |
*/ | |
mReceiverRegistrar.safeRegisterReceiver(mBatteryReceiver, | |
mBatteryFilter); | |
mReceiverRegistrar.safeRegisterReceiver(mConnectivityReceiver, | |
mConnectivityFilter); | |
} | |
private void onBatteryLow() { | |
/* | |
* Maybe when the battery goes low you want to unregister a few | |
* receivers? | |
*/ | |
mReceiverRegistrar.safeUnregisterReceiver(mConnectivityReceiver); | |
} | |
@Override | |
protected void onPause() { | |
super.onPause(); | |
/* | |
* In onPause, unregister all remaining registered receivers | |
*/ | |
mReceiverRegistrar.safeUnregisterAllReceivers(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment