观察者 update() 导致 NullPointerException

Observer update() causing a NullPointerException

我正在尝试使用观察者模式通知 BroadcastReceiver 的观察者已收到新消息。当调用 activity 中的 update() 方法时,应更新 activity 中的字段,以便消息可以显示在屏幕上。但是,那时我一直收到 NullPointerException

以下是相关日志的摘录:

04-15 13:03:21.252  31107-31107/com.example.sam.yak E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.sam.yak, PID: 31107
java.lang.RuntimeException: Unable to start receiver com.example.sam.yak.Receive: java.lang.NullPointerException
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:2698)
        at android.app.ActivityThread.access00(ActivityThread.java:153)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1434)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5633)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException
        at com.example.sam.yak.SendActivity.update(SendActivity.java:94)
        at com.example.sam.yak.Receive.notifyObservers(Receive.java:82)
        at com.example.sam.yak.Receive.onReceive(Receive.java:53)
        at android.app.ActivityThread.handleReceiver(ActivityThread.java:2687) at android.app.ActivityThread.access00(ActivityThread.java:153) at       android.app.ActivityThread$H.handleMessage(ActivityThread.java:1434) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:157) at android.app.ActivityThread.main(ActivityThread.java:5633) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:896) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712) at dalvik.system.NativeStart.main(Native Method)

SendActivity(观察者)的相关代码如下:

public class SendActivity extends Activity implements Observer {

private static SendActivity send;
String message;
String sender;
Receive receive;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_send);
    sender = "";
    message = "";
    receive = Receive.getInstance();
}

public static synchronized SendActivity getInstance() {
    if (send == null)
        send = new SendActivity();
    return send;
}


@Override
public void update() {
    message = receive.getMessage();
    sender = receive.getSenderNumber();
    retrieve();
}

此外,Receive(可观察对象)的相关代码:

public class Receive extends BroadcastReceiver {

public static Receive receive;
String sender = "";
String message = "";
List<Observer> observers = new ArrayList<>();
SendActivity send = SendActivity.getInstance();

public Receive() {}

public static synchronized Receive getInstance() {
    if (receive == null)
        receive = new Receive();
    return receive;
}

/**
 *
 * @param context
 * @param intent
 */
@Override
public void onReceive(Context context,Intent intent) {
    //newMsg = false;
    addObserver(send);
    Bundle bundle = intent.getExtras();
    if(!(bundle == null)) {
        Object[] pdus = (Object[])bundle.get("pdus");
        SmsMessage[] msgs = new SmsMessage[pdus.length];
        for (int i = 0; i < msgs.length; i++) {
            msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
            //newMsg = true;
            setSender(msgs[i].getOriginatingAddress());
            setMessage(msgs[i].getMessageBody());
            Toast.makeText(context,msgs[i].getMessageBody(),Toast.LENGTH_SHORT).show();
            notifyObservers();
        }
    }
}

public void setSender(String s) {
    sender = s;
}

public void setMessage(String s) {
    message = s;
}

public String getSenderNumber() {
    return sender;
}

public String getMessage() {
    return message;
}

public void addObserver(Observer o) {
    if((o != null) && (!observers.contains(o))){
        observers.add(o);
    }
}

public void notifyObservers() {
    for(Observer l : observers) {
        l.update();
    }
}
}

非常感谢任何反馈和建议。

为什么不尝试用空值显式初始化“send”变量。

私有静态 SendActivity 发送;

改为

private static SendActivity send = null;

Activity 生命周期由 Android 操作系统管理。

我不建议将您的活动和广播接收器设为单例,因为您不知道它们何时创建,是否为空。

我对你的问题的解决方案是使用某种事件总线,而不是观察者模式。

greenrobot 的 EventBus 非常棒:https://github.com/greenrobot/EventBus 而且也不难学,

我不能确定,但​​我认为你对单例的使用是有问题的。假设先创建 SendActivity。在它的 onCreate 方法中调用 Receive.getInstance(),它又调用 SendActivity.getInstance()SendActivity 实例还没有准备好。我认为您的 Receive class 没有正确初始化。