简体   繁体   English

我的在线状态更改时,Android Broadcastreceiver崩溃

[英]Android Broadcastreceiver crashes when my onlinestate changes

I have extended a Broadcastreceiver so that my app knows whenever the online state has been changed. 我扩展了Broadcastreceiver,以便我的应用程序知道何时更改了在线状态。 The thing is: whenever the online state changes, my broadcastreceiver seems to get reconstructed. 关键是:每当在线状态发生变化时,我的广播接收器似乎就会重建。 Because I add a listener on a later moment than the constructor, my listener is empty and I get a NullPointerException: 因为我在构造函数之后添加了侦听器,所以我的侦听器为空,并且得到了NullPointerException:

02-07 11:11:45.804: E/AndroidRuntime(21416): FATAL EXCEPTION: main
02-07 11:11:45.804: E/AndroidRuntime(21416): java.lang.RuntimeException: Unable to start receiver nl.raakict.android.dnd.util.NetworkStateReceiver: java.lang.NullPointerException
02-07 11:11:45.804: E/AndroidRuntime(21416):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2699)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at android.app.ActivityThread.access$1500(ActivityThread.java:162)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1453)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at android.os.Handler.dispatchMessage(Handler.java:99)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at android.os.Looper.loop(Looper.java:158)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at android.app.ActivityThread.main(ActivityThread.java:5751)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at java.lang.reflect.Method.invokeNative(Native Method)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at java.lang.reflect.Method.invoke(Method.java:511)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1083)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:850)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at dalvik.system.NativeStart.main(Native Method)
02-07 11:11:45.804: E/AndroidRuntime(21416): Caused by: java.lang.NullPointerException
02-07 11:11:45.804: E/AndroidRuntime(21416):    at nl.raakict.android.dnd.util.NetworkStateReceiver.onReceive(NetworkStateReceiver.java:38)
02-07 11:11:45.804: E/AndroidRuntime(21416):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2687)
02-07 11:11:45.804: E/AndroidRuntime(21416):    ... 10 more

My custom broadcastreceiver looks like this: 我的自定义广播接收器如下所示:

package nl.raakict.android.dnd.util;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.Log;

public class NetworkStateReceiver extends BroadcastReceiver{ 
    private Listener mListener = null;
    private static NetworkStateReceiver _instance;

    public static NetworkStateReceiver getInstance()
    {
        if (_instance == null)
        {
            _instance = new NetworkStateReceiver();
        }
        return _instance;
    }

    public NetworkStateReceiver(){
    }

    @Override
    public void onReceive(Context context, Intent intent) {
     Log.d("app","Network connectivity change");
     if(intent.getExtras()!=null) {
        NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
        if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) {
            Log.i("app","Network "+ni.getTypeName()+" connected");
            mListener.onStateChange(true);
        }
     }
     if(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
            Log.d("app","There's no network connectivity");
            mListener.onStateChange(false);
     }
   }

    public interface Listener {
        public void onStateChange(boolean state);
    }

    public void registerListener (Listener listener) {
        mListener = listener;
    }

    public boolean isOnline(Context context) {
        ConnectivityManager cm =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) {
            return true;
        }
        return false;
    }

}

and my manifest: 和我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="nl.raakict.android.dnd"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="nl.raakict.android.dnd.HomeActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:theme="@style/FullscreenTheme" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
            <receiver android:name="nl.raakict.android.dnd.util.NetworkStateReceiver">
           <intent-filter>
              <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
           </intent-filter>
        </receiver>
    </application>
</manifest>

And this is my listener class: 这是我的侦听器类:

public class RequestHandler implements NetworkStateReceiver.Listener {

    private static RequestHandler _instance;
    private NetworkStateReceiver networkStateReveiver;
    private ArrayList<CustomJsonRequest> delayedRequestQueue;
    private boolean currentlyOnline;
    private Context applicationContext;


    public static RequestHandler getInstance(Context applicationContext)
    {
        if (_instance == null)
        {
            _instance = new RequestHandler(applicationContext);
        }
        return _instance;
    }

    private RequestHandler(Context applicationContext){
        delayedRequestQueue= new ArrayList<CustomJsonRequest>();
        this.applicationContext = applicationContext;
        networkStateReveiver = NetworkStateReceiver.getInstance();
        networkStateReveiver.registerListener(this);
        currentlyOnline = networkStateReveiver.isOnline(applicationContext);
    }

    @Override
    public void onStateChange(boolean online) {
        // TODO Auto-generated method stub
        currentlyOnline = online;
        if(online){
            sendRequestQueue();
        }
    }

    public void newPostRequest(CustomJsonRequest request) {
        delayedRequestQueue.add(request);
        if(currentlyOnline) 
            sendRequestQueue();
    }

    public void sendRequestQueue(){
        //code logic here
    }
}

What did I do wrong? 我做错了什么?

The problem is that when Network State is being done, Android will create your NetworkStateReceiver class instance, call its onReceive and then destroy your receiver instance. 问题在于,完成网络状态后,Android将创建您的NetworkStateReceiver类实例,调用其onReceive ,然后销毁您的接收器实例。 So that is why your listener is always null, if you want to inform some other components of network change then you should for example send local broadcast in your application. 这就是为什么您的侦听器始终为null的原因,如果您想通知网络更改的其他某些组件,则应例如在应用程序中发送本地广播。

You might alswo register local BroadcastReceiver: 您可能还会注册本地BroadcastReceiver:

"Register your BroadcastReceiver programmatically": http://www.grokkingandroid.com/android-tutorial-broadcastreceiver/ “以编程方式注册您的BroadcastReceiver”: http : //www.grokkingandroid.com/android-tutorial-broadcastreceiver/

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

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