android - Activity 已泄漏 IntentReceiver 错误

标签 android broadcastreceiver

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

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

我的代码:

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() 方法上收到错误。有什么想法吗?

最佳答案

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

这不是很健壮的代码。您不需要每次都创建 BroadcastReceiver 的新实例。您应该做的是在 onCreate() 中为每个 BroadcastReceiver 创建一个实例。然后在您的类中声明一个名为 receiversRegistered 的 bool 成员变量。在 registerReceivers() 中,您应该检查此 bool 值。如果它是 true,则接收者已经注册,您什么都不应该做。如果不是,则注册接收器,然后将 bool 值设置为 true。当您注销接收器时,将 bool 值设置为 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;
        }
    }
}

关于android - Activity 已泄漏 IntentReceiver 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40891105/

相关文章:

android - 赋予广播接收器最高优先级的整数值是多少?

java - 如何找出哪个 Activity 启动了触发您的 BroadCastReceiver 的 Intent ?

java - 按顺序播放帧动画。安卓

android - 如何检测用户何时在 android 设备上插入耳机? (与 ACTION_AUDIO_BECOMING_NOISY 相反)

android - 如何在启动街景 Intent 之前判断街景是否存在

android - Android 中的应用内结算 - 问题

android - Broadcastreceiver 发出的通知在被反压时关闭应用程序

java - Android Java - 警报管理器大部分工作完美,但有时会延迟

android - 迁移到 Google Play 服务后,广告系列跟踪不起作用

android - 应用程序关闭后粘性服务重新启动