Activity已泄露IntentReceiver错误

时间:2016-11-30 14:37:56

标签: android broadcastreceiver

在将此帖标记为已关闭或重复之前,我想说我已经完成了类似帖子中提到的所有内容,但没有一个有效。

我有2个接收器可以从中获取数据。所以我想在活动开始时注册接收者,并在活动不可见时注销它们。

我的代码:

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();
        }
    }
}

收件人代码:

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();
                }
            }
        }
    }
}

和电池接收器:

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();
            }
        }
    }
}

我在registerReceivers()方法上收到错误。有什么想法吗?

2 个答案:

答案 0 :(得分:6)

您在onCreate()中注册接收者,然后在onResume()中注册。这会泄漏您在onCreate()中注册的接收者,因为每次调用registerReceivers()时,您都会覆盖用于保存对它们的引用的变量。

这不是非常强大的代码。您不需要每次都创建BroadcastReceiver的新实例。您应该做的是在BroadcastReceiver中创建每个onCreate()的一个实例。然后在类中声明一个名为receiversRegistered的布尔成员变量。在registerReceivers()中你应该检查这个布尔值。如果是true,接收者已经注册,你什么都不做。如果没有,请注册接收器,然后将布尔值设置为true。取消注册接收器时,将布尔值设置为false

编辑:这一切都是为您完成的:

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;
        }
    }
}

答案 1 :(得分:0)

移动unregisterReceiver内的onPause不在onDestroy

当您的活动在后台移动时onDestroy未被调用。该活动仅暂停。当应用程序手动关闭或由系统关闭时,将调用onDestroy

(在上述情况下onPause之前调用onDestroy