Java 已初始化的对象在BroadcastListener方法onReceive中设置为null

Java 已初始化的对象在BroadcastListener方法onReceive中设置为null,java,android,interface,nullreferenceexception,Java,Android,Interface,Nullreferenceexception,我的类NetworkListener应该检查Internet连接是否可用。然后,它应该显示一个带有InternetState的Snackbar。为此,我使用了一个接口 我的全部代码: [MainActivity.java]: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activ

我的类NetworkListener应该检查Internet连接是否可用。然后,它应该显示一个带有InternetState的Snackbar。为此,我使用了一个接口

我的全部代码:

[MainActivity.java]:

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

    setContentView(R.layout.activity_main);
    setTitle(R.string.Inbox);

    Initialize_NavigationDrawer();

    Initialize_Objects();

    //1. Here, I initialise my NetworkListener and register my Receiver
    NetworkListener mNetworkListener = new NetworkListener();
    mNetworkListener.registerReceiver(this);
}

@Override
public void ToggleSnackbar(boolean ShowHide) {
    if (ShowHide) snbNoInternet.show();
    else snbNoInternet.dismiss();
}
[NetworkListener.java]:

public class NetworkListener extends BroadcastReceiver {

    private SnackbarInterface snbInterface;

    public NetworkListener() {}

    @Override
    public void onReceive(Context context, Intent intent) {
        //4. After toggling the Network-Connection, a NullReferenceException occurs
        //5. System.out.println(snbInterface) shows: null
        ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        if (ni == null || !ni.isConnected()) {
            snbInterface.ToggleSnackbar(true);
        }
        else if (ni != null && ni.isConnected()) {
            snbInterface.ToggleSnackbar(false);
        }
    }

    public void registerReceiver(SnackbarInterface receiver) {
        snbInterface = receiver; //2. Is called from onCreate

        //3. System.out.println(snbInterface) shows: at.guger.email.activities.MainActivity@27472a5e
    }

    public interface SnackbarInterface {
        public void ToggleSnackbar(boolean ShowHide);
    }
}
[AndroidManifest.xml]:

<activity
    android:name=".activities.MainActivity" >

    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>

</activity>

<activity
    android:name=".activities.WriteActivity" />
<activity
    android:name=".activities.ReadActivity" />

<receiver
    android:name=".NetworkListener">
    <intent-filter>
        <action
            android:name="android.net.conn.CONNECTIVITY_CHANGE" />
    </intent-filter>
</receiver>

以及权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

代码被调用就像数字被排序一样! 我真的无法解释为什么snbInterface设置为null


我希望你能帮助我

您使用AndroidManifest中的
receiver
元素注册了
BroadcastReceiver
。Android系统创建BroadcastReceiver实例,并使用适当的参数调用
onReceive
方法

如果要使用
BroadcastReceiver
操作应用程序的UI(如显示/隐藏
Snackbar
),则必须使用
registerReceiver(BroadcastReceiver,IntentFilter IntentFilter)在活动中注册接收器
在活动的
onCreate
方法中,以及
onestory
方法中取消注册

从AndroidManifest.xml文件中删除
receiver
元素,并通过代码创建BroadcastReceiver

这个问题清楚地解释了如何创建和注册广播接收器:

在BroadcastReceive的onReceive方法中,在活动中调用
toggleSnackbar
方法以切换Snackbar

还有一种方法可以实现你想要的。这里讨论的是:

阅读更多关于广播接收机的信息


您可以将接收器作为单独的类编写。实例化接收器并调用
registerReceiver
,第一个参数作为接收器,第二个参数作为IntentFilter。

我可以将接收器放入外部类吗?@U dani更新了答案。因此,如果我是对的:广播接收器必须在它应该拥有的类中实例化access?实例化是创建BroadcastReceiver的对象。它可以在任何地方进行。BroadcastReceiver的定义与Activity类的成员访问有关。如果需要访问活动成员,则应将BroadcastReceiver定义为内部类。内部类可以访问外部类成员。如果您的逻辑不需要访问Activity类,那么您可以独立定义BroadcastReceiver,并调用Activity的registerReceiver,将receiver的对象传递给它。