Observer update()导致NullPointerException

时间:2015-04-15 12:21:31

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

我正在尝试使用Observer模式向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();
    }
}
}

任何反馈&amp;建议非常感谢。

3 个答案:

答案 0 :(得分:1)

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

我不建议让你的活动和广播接收器单独使用,因为你不知道它们何时被创建,它们是否为空。

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

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

答案 1 :(得分:1)

我无法确定,但我认为您对单身人士的使用存在问题。假设首先创建SendActivity。调用onCreate方法Receive.getInstance(),然后调用SendActivity.getInstance(),但SendActivity实例尚未就绪。我不认为您的Receive类已经正确初始化。

答案 2 :(得分:-1)

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

私有静态SendActivity发送;

将其更改为,

private static SendActivity send = null;