[英]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
广播由系统发送。 这意味着您当前的设置有几件事情。
您正在LocalBroadcastManager
注册的BroadcastReceiver
实例将永远不会收到该广播,因为LocalBroadcastManager
仅处理来自应用程序内部的广播。
在清单中注册Receiver类意味着系统将实例化Receiver的新实例来处理每个广播。 由于尚未将这些实例作为侦听器传递给您的Activity
实例, networkStateListener
onReceive()
networkStateListener
将为null,这很可能是您当前NullPointerException
的来源。
根据所需的行为,您可以选择几种方式。
如果仅想在Activity
运行时收到连接更改的通知,请执行以下操作:
而是使用Context#registerReceiver()
方法Context#registerReceiver()
Receiver的实例,然后从清单中删除<receiver>
条目。 如果将NetworkStateReceiver
HomeActivity
的内部类,则不需要该接口。
使用LocalBroadcastManager
在NetworkStateReceiver
和您的Activity
之间(而不是您的侦听器interface
。 您可以在Intent
上使用额外的内容来指示连接状态,或者使用其他操作来区分。
使用其他事件总线实现在Receiver和Activity
之间进行通信。
如果即使在应用未运行时也希望收到有关更改的通知,请执行以下操作:
Activity
,并在Intent
上附加一个附加符号以指示连接状态。 如果将Activity
的launchMode
为singleTask
或singleTop
,并覆盖其onNewIntent()
方法,则这也可以处理Activity
已经运行的情况。 在任何情况下,都没有必要将Activity
作为侦听器传递给BroadcastReceiver
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.