在广播接收器中添加自定义侦听器可在Android中提供NPE

时间:2016-04-15 17:06:42

标签: android broadcastreceiver listener android-broadcastreceiver custom-event

我在这里遇到了一个问题。我正在尝试通过实现广播接收器来监听连接变化。我还在广播接收器中初始化了一个自定义侦听器,以便与活动进行通信,以显示连接变化以显示一个Crouton Toast。各种类的代码如下:

广播接收器:

public class NetworkStateReceiver extends BroadcastReceiver {

    private NetworkStateListener networkStateListener;

    public NetworkStateReceiver() {
    }

    public NetworkStateReceiver(NetworkStateListener networkStateListener) {
        this.networkStateListener = networkStateListener;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("test", "Network connectivity change ::: " + this.networkStateListener);
        if (intent.getExtras() != null) {

            NetworkInfo ni = (NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
            if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
                Log.i("test", "Network " + ni.getTypeName() + " connected");
                networkStateListener.onConnected();
            }
        }
        if (intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
            Log.d("test", "There's no network connectivity");
            networkStateListener.onDisconnected();
        }
    }
}

自定义侦听器界面:

public interface NetworkStateListener {

    public void onConnected();

    public void onDisconnected();
}

实现侦听器的活动和接收器注册连接更改:

    public class HomeActivity extends AppCompatActivity implements NetworkStateListener {
     private NetworkStateReceiver mReceiver;
     private LocalBroadcastManager mBroadcastManager;
    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
      mBroadcastManager =    LocalBroadcastManager.getInstance(HomeActivity.this);
        mReceiver = new NetworkStateReceiver(HomeActivity.this);
    }

@Override
    protected void onResume() {
        super.onResume();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(android.net.ConnectivityManager.CONNECTIVITY_ACTION);
        mBroadcastManager.registerReceiver(mReceiver, intentFilter);
    }

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

这是明显的条目:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test">

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

 <application
        android:name=".TestApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"

<receiver android:name=".shared.receivers.NetworkStateReceiver">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
            </intent-filter>
        </receiver>
    </application>

</manifest>

我不知道为什么networkstateListener没有被初始化。它给出了一个空指针,表示NetWorkStateListener可能没有被初始化。有人可以帮我解决这个问题吗?我过去已经实现了这一点,但是通过自定义广播而不是这些系统广播。

1 个答案:

答案 0 :(得分:2)

CONNECTIVITY_CHANGE广播由系统发送。这对您当前的设置意味着一些事情。

  1. 您在BroadcastReceiver注册的LocalBroadcastManager实例将永远不会收到该广播,因为LocalBroadcastManager仅处理来自您应用内的广播。

  2. 在清单中注册Receiver类意味着系统将实例化Receiver的新实例以处理每个广播。由于这些实例不会被Activity作为收听者的实例传递,networkStateListener中的onReceive()将为空,这很可能是您当前NullPointerException即将到来的地方从

  3. 根据您的期望行为,您可以选择一些选项。

    如果您只是希望在Activity正在运行时收到有关连接更改的通知:

    1. 使用Context#registerReceiver()方法注册Receiver的实例,并从清单中删除<receiver>条目。如果您将NetworkStateReceiver设为HomeActivity的内部类,则不需要该界面。

    2. 使用LocalBroadcastManagerNetworkStateReceiver和您的Activity之间进行通信,而不是在您的听众interface之间进行通信。您可以在Intent上使用额外信息来指示连接状态,或者使用不同的操作来区分。

    3. 使用其他一些事件总线实现在Receiver和Activity之间进行通信。

    4. 如果您希望即使应用未运行也会收到更改通知:

      1. 从接收器启动Activity并附加一个额外的Intent以指示连接状态。如果您将Activity的{​​{1}}设置为ActivitylaunchMode,并覆盖其singleTask,这也可以处理singleTop已经投放的情况1}}方法。
      2. 在任何情况下,将onNewIntent()作为聆听者传递给Activity都不是必需的。