Reputation:
before marking this post as closed or duplicate i want to say that i have done all the things that are mentioned on similar posts but none of them worked.
I have 2 receivers which i get data from. So i want to register the receivers when the activity starts and unregister them when the activity is not visible.
My Code:
public class MainActivity extends AppCompatActivity {
private CheckNetworkStatusReceiver checkNetworkStatusReceiver;
private CheckBatteryStatusReceiver checkBatteryStatusReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkConnection();
}
public void checkConnection() {
if(!ConnectionManager.isNetworkAvailable(MainActivity.this)){
ConnectionManager.wifiSettingsDialog(MainActivity.this).show();
}else{
registerReceivers();
}
}
public void registerReceivers() {
checkNetworkStatusReceiver = new CheckNetworkStatusReceiver();
checkBatteryStatusReceiver = new CheckBatteryStatusReceiver();
registerReceiver(checkNetworkStatusReceiver, new IntentFilter(Constants.INTENT_FILTER_CONNECTIVITY_CHANGE));
registerReceiver(checkBatteryStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
@Override
protected void onDestroy() {
super.onDestroy();
try{
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
protected void onResume() {
registerReceivers();
super.onResume();
}
@Override
protected void onRestart() {
registerReceivers();
super.onRestart();
}
@Override
protected void onStop() {
super.onStop();
try{
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
}catch (Exception e){
e.printStackTrace();
}
}
}
The receiver code:
public class CheckNetworkStatusReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null){
Log.e("Action ",intent.getAction());
if(intent.getAction().equalsIgnoreCase(Constants.INTENT_FILTER_CONNECTIVITY_CHANGE)) {
if (!ConnectionManager.isNetworkAvailable(context)){
Toast.makeText(context, R.string.no_internet, Toast.LENGTH_SHORT).show();
}
if (MobileDataManager.slowInternetConnection(context)){
Toast.makeText(context, R.string.slow_internet_delay, Toast.LENGTH_SHORT).show();
}
}
}
}
}
and the battery receiver:
public class CheckBatteryStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null){
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
if (level <= 15){
Toast.makeText(context, "Batter level " + level + "% is very low. Please connect to a charger.", Toast.LENGTH_SHORT).show();
}
}
}
}
i get the error on the registerReceivers()
method. Any ideas?
Upvotes: 2
Views: 9345
Reputation: 95626
You register the receivers in onCreate()
and then again in onResume()
. This will leak the receivers that you registered in onCreate()
, because you overwrite the variables you are using to hold references to them every time registerReceivers()
is called.
This is not very robust code. You don't need to create new instances of the BroadcastReceiver
every time. What you should do is to create one instance of each BroadcastReceiver
in onCreate()
. Then declare a boolean member variable in your class called receiversRegistered
. In registerReceivers()
you should check this boolean. If it is true
, the receivers are already registered and you should do nothing. If not, register the receivers and then set the boolean to true
. When you unregister the receivers, set the boolean to false
.
EDIT: Here it is all done for you:
public class MainActivity extends AppCompatActivity {
private CheckNetworkStatusReceiver checkNetworkStatusReceiver;
private CheckBatteryStatusReceiver checkBatteryStatusReceiver;
private boolean receiversRegistered;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkNetworkStatusReceiver = new CheckNetworkStatusReceiver();
checkBatteryStatusReceiver = new CheckBatteryStatusReceiver();
checkConnection();
}
public void checkConnection() {
if(!ConnectionManager.isNetworkAvailable(MainActivity.this)){
ConnectionManager.wifiSettingsDialog(MainActivity.this).show();
}else{
registerReceivers();
}
}
public void registerReceivers() {
// Only register if not already registered
if (!receiversRegistered) {
registerReceiver(checkNetworkStatusReceiver, new IntentFilter(Constants.INTENT_FILTER_CONNECTIVITY_CHANGE));
registerReceiver(checkBatteryStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
receiversRegistered = true;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (receiversRegistered) {
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
}
}
@Override
protected void onResume() {
registerReceivers();
super.onResume();
}
@Override
protected void onRestart() {
registerReceivers();
super.onRestart();
}
@Override
protected void onStop() {
super.onStop();
if (receiversRegistered) {
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
receiversRegistered = false;
}
}
}
Upvotes: 7
Reputation: 2180
Move the unregisterReceiver
inside onPause
not in onDestroy
.
When your activity is moved in background onDestroy
is not called. The activity is only paused. onDestroy
is called when the app is closed manually or by the system.
(onPause
is called before onDestroy
in above situation)
Upvotes: 0