【问题标题】:Adding a custom listener inside a broadcast receiver gives NPE in Android在广播接收器中添加自定义侦听器会在 Android 中提供 NPE
【发布时间】:2016-04-15 17:06:41
【问题描述】:

我在这里遇到了一个问题。我正在尝试通过实现广播接收器来监听连接更改。此外,我已经在广播接收器中初始化了一个自定义侦听器,以便与活动通信以显示要显示的连接更改一个面包圈吐司。各种类的代码如下:

广播接收器:

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 可能没有被初始化。有人可以帮我解决这个问题吗?我过去已经实现了这一点,但是使用自定义广播而不是这些系统广播。

【问题讨论】:

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


    【解决方案1】:

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

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

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

      李>

    根据您想要的行为,您有几个选项可供选择。

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

    1. 改为使用Context#registerReceiver() 方法注册接收器实例,并从清单中删除&lt;receiver&gt; 条目。如果将NetworkStateReceiver 设为HomeActivity 的内部类,则不需要该接口。

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

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

    如果您希望在应用未运行时也能收到更改通知:

    1. 从接收器启动您的Activity,并在Intent 上附加一个额外的附件以指示连接状态。如果您将Activity 的launchMode 设置为singleTask 或singleTop,并覆盖其onNewIntent() 方法,这也可以处理您的Activity 已经运行的情况。

    无论如何,将您的Activity 作为侦听器传递给您的BroadcastReceiver 并不是真正必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 1970-01-01
      • 1970-01-01
      • 2017-11-18
      相关资源
      最近更新 更多