0

目的是在我的 Android 应用程序中实现一个BroadcastReceiver,它可以动态检测设备何时更改其与 Internet 的连接或断开连接状态。我已经尝试了几个教程和解决方案建议,但我仍然无法使其正常工作,而且我总是得到相同的:“泄漏的 IntentReceiver ”错误。

相关代码是:首先,我写了一个从BroadcastReceiver类派生的类:

public class InternetConnector_Receiver extends BroadcastReceiver {
   public InternetConnector_Receiver() {}

   @Override
   public void onReceive(Context context, Intent intent) {
      try {
             boolean isVisible = MyApplication.isActivityVisible();// Check if activity is visible or not
             Log.i("Activity is Visible ", "Is activity visible : " + isVisible);

             // If it is visible then trigger the task else do nothing
                if (isVisible == true) {
                   ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                   NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

                   // Check internet connection and accrding to state change then text of activity by calling method
                   if (networkInfo != null && networkInfo.isConnected()) {
                      new LMMoviesMainActivity().TTSstatusDataNetChanged(true);
                   } else {
                      new LMMoviesMainActivity().TTSstatusDataNetChanged(false);
                   }
                }
     } catch (Exception e) {
        e.printStackTrace();
     }
  }
}

然后,我在 LMMoviesMainActivity 中创建相关变量。

问题:添加到IntentFilter 中的 3 个 Action是否正确激活了对 Internet 连接的检测?如果它们不正确,那么正确的值是什么?

private IntentFilter internetConnectionGloIntentFilter;
private InternetConnector_Receiver objGloInternetConnectorReceiver;
internetConnectionGloIntentFilter = new IntentFilter();
internetConnectionGloIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
internetConnectionGloIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
internetConnectionGloIntentFilter.addAction("android.net.wifi.STATE_CHANGE");
objGloInternetConnectorReceiver = new InternetConnector_Receiver();
registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);

最后,包含在 Internet 连接发生变化时执行的指令的函数:

public void TTSstatusDataNetChanged(boolean isConnectedBool) {
   unregisterReceiver(objGloInternetConnectorReceiver);
   registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);

   // Change status according to boolean value
   if (isConnectedBool) {

      if (ttsSettingsGloDialog.isShowing()) {
         ttsWarningsGloTextView.setText( "Net ON" );
      }

      dataNetConnectedGloBool = true;
   } else {

      if (ttsSettingsGloDialog.isShowing()) {
         ttsWarningsGloTextView.setText( "Net Off" );
      }

      dataNetConnectedGloBool = false;
   }
}

尝试执行:unregisterReceiver,我收到消息:

服务 com.google.android.youtube.api.service.YouTubeService 泄露了最初在这里注册的 IntentReceiver wuq@3967361。您是否错过了对 unregisterReceiver() 的调用?

但是我想我必须取消注册 Receiver,然后重新注册,为下一个连接事件做好准备,对吧?如果当前的 unregisterReceiver 不是指触发的意图或事件,那么如何正确编写指令并关联呢?

我检查了 Intent 触发的调试器,并且BroadcastReceiver接收到事件,但我只是不知道如何克服这个泄漏的错误。有任何想法吗?我错过了一些重要的东西吗?你看出什么错误了吗?感谢您的关注。

4

3 回答 3

1

您只需注册一次广播接收器,而不是每次都注册。每次注册广播接收器时,您都必须注销它。每次在方法内部注册都会导致泄漏。删除它并仅在 onResume 中注册并在暂停。

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);
}

@Override
protected void onPause() {
    unregisterReceiver(objGloInternetConnectorReceiver);
    super.onPause();
}
于 2017-10-30T09:46:45.977 回答
1

在您的LMMoviesMainActivityobjGloInternetConnectorReceiver的回调中取消注册您的接收器OnDestroy()

 @Override
     protected void onDestroy() {
            super.onDestroy();

          unregisterReceiver(objGloInternetConnectorReceiver);

        }
于 2017-10-30T09:37:56.793 回答
1

您的代码中有几个问题。onResume()如果您在中注册接收器并在中取消注册,则无需检查 Activity 是否可见onPause()

if (networkInfo != null && networkInfo.isConnected()) {
    new LMMoviesMainActivity().TTSstatusDataNetChanged(true);
} else {
    new LMMoviesMainActivity().TTSstatusDataNetChanged(false);
}

那是行不通的,因为您需要引用实际的 Activity 而不是新的。如果您将 BroadcastReceiver 放在 LMMoviesMainActivity 中,只需执行

if (networkInfo != null && networkInfo.isConnected()) {
    LMMoviesMainActivity.this.TTSstatusDataNetChanged(true);
} else {
    LMMoviesMainActivity.this.TTSstatusDataNetChanged(false);
}

此外,当您收到广播时,您不必取消注册并注册新的广播接收器。所以删除这些行:

unregisterReceiver(objGloInternetConnectorReceiver);
registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);

这是一个应该工作的完整示例:(不要忘记初始化 ttsSettingsGloDialog、ttsWarningsGloTextView 和 dataNetConnectedGloBool)

package com.test;

import android.app.Activity;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.TextView;

public class LMMoviesMainActivity extends Activity {

    private IntentFilter internetConnectionGloIntentFilter;
    private InternetConnector_Receiver objGloInternetConnectorReceiver;

    private Dialog ttsSettingsGloDialog;
    private TextView ttsWarningsGloTextView;
    private boolean dataNetConnectedGloBool;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        internetConnectionGloIntentFilter = new IntentFilter();
        internetConnectionGloIntentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        internetConnectionGloIntentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
        internetConnectionGloIntentFilter.addAction("android.net.wifi.STATE_CHANGE");

        objGloInternetConnectorReceiver = new InternetConnector_Receiver();
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(objGloInternetConnectorReceiver, internetConnectionGloIntentFilter);
    }

    @Override
    protected void onPause() {
        unregisterReceiver(objGloInternetConnectorReceiver);
        super.onPause();
    }

    public void TTSstatusDataNetChanged(boolean isConnectedBool) {
        // Change status according to boolean value
        if (isConnectedBool) {

            if (ttsSettingsGloDialog.isShowing()) {
                ttsWarningsGloTextView.setText( "Net ON" );
            }

            dataNetConnectedGloBool = true;
        } else {

            if (ttsSettingsGloDialog.isShowing()) {
                ttsWarningsGloTextView.setText( "Net Off" );
            }

            dataNetConnectedGloBool = false;
        }
    }

    public class InternetConnector_Receiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

                // Check internet connection and accrding to state change then text of activity by calling method
                if (networkInfo != null && networkInfo.isConnected()) {
                    LMMoviesMainActivity.this.TTSstatusDataNetChanged(true);
                } else {
                    LMMoviesMainActivity.this.TTSstatusDataNetChanged(false);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
于 2017-10-30T09:44:04.787 回答