繁体   English   中英

在广播接收器内添加自定义侦听器可在Android中获得NPE

[英]Adding a custom listener inside a broadcast receiver gives NPE in Android

我在这里遇到了一个问题,我正在尝试通过实现广播接收器来侦听连接性更改,还初始化了广播接收器中的自定义侦听器,以便与活动进行有关连接性更改的通信以显示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可能没有被初始化。有人可以帮我这个忙吗? 过去,我是通过自定义广播而不是通过此类系统广播来实现的。

CONNECTIVITY_CHANGE广播由系统发送。 这意味着您当前的设置有几件事情。

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

  2. 在清单中注册Receiver类意味着系统将实例化Receiver的新实例来处理每个广播。 由于尚未将这些实例作为侦听器传递给您的Activity实例, networkStateListener onReceive() networkStateListener将为null,这很可能是您当前NullPointerException的来源。

根据所需的行为,您可以选择几种方式。

如果仅想在Activity运行时收到连接更改的通知,请执行以下操作:

  1. 而是使用Context#registerReceiver()方法Context#registerReceiver() Receiver的实例,然后从清单中删除<receiver>条目。 如果将NetworkStateReceiver HomeActivity的内部类,则不需要该接口。

  2. 使用LocalBroadcastManagerNetworkStateReceiver和您的Activity之间(而不是您的侦听器interface 您可以在Intent上使用额外的内容来指示连接状态,或者使用其他操作来区分。

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

如果即使在应用未运行时也希望收到有关更改的通知,请执行以下操作:

  1. 从接收器开始您的Activity ,并在Intent上附加一个附加符号以指示连接状态。 如果将ActivitylaunchModesingleTasksingleTop ,并覆盖其onNewIntent()方法,则这也可以处理Activity已经运行的情况。

在任何情况下,都没有必要将Activity作为侦听器传递给BroadcastReceiver

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM