【问题标题】:Observer update() causing a NullPointerException观察者 update() 导致 NullPointerException
【发布时间】:2015-04-15 12:21:31
【问题描述】:

我正在尝试使用观察者模式来通知BroadcastReceiver 的观察者已收到一条新消息。当调用活动中的update() 方法时,活动中的字段应该被更新,以便消息可以显示在屏幕上。但是,那时我一直收到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.access$1700(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.access$1700(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();
    }
}
}

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

【问题讨论】:

  • 您好,感谢您的回答。哪些字符串?发件人和消息字段已经初始化。
  • 我认为receive 尚未初始化。如果接收为空,则receive.getMessage(); 将抛出 NullPointerException
  • 我删除了所有不必要的代码。第 94 行是:message = receive.getMessage();在 SendActivity
  • Receive 是一个单例,所以我在 SendActivity 中初始化为 receive = Receive.getInstance()
  • sendActivity 中的第 94 行?

标签: java android android-activity singleton observer-pattern


【解决方案1】:

我不能确定,但​​我认为您对单例的使用存在问题。假设首先创建SendActivity。在其onCreate 方法中调用Receive.getInstance(),而后者又调用SendActivity.getInstance(),但SendActivity 实例尚未准备好。我认为您的 Receive 类从未正确初始化。

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      私有静态 SendActivity 发送;

      改成,

      私有静态 SendActivity send = null;

      【讨论】:

        猜你喜欢
        • 2015-12-13
        • 2015-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多