当我的应用程序没有运行时(仅在未运行时),为什么我的BroadcastReceiver会给我一个nullpointer异常?

时间:2011-12-19 20:33:19

标签: android broadcastreceiver

我会简单地总结一下因为我的原始代码很长。假设我的广播接收器是这样的:

public class SMSBroadcastReceiver extends BroadcastReceiver {

    static ArrayList<String> phonenumber_array = new ArrayList<String>();
    static ArrayList<String> message_array = new ArrayList<String>();

       @Override
       public void onReceive(Context context, Intent intent) {

        Bundle bundle = intent.getExtras();

        if (bundle != null) {

        Object[] pdus = (Object[]) bundle.get("pdus");
        SmsMessage[] sms = new SmsMessage[pdus.length];

        for (int i = 0; i < sms.length; i++) {

        sms[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);

           phonenumber_array.add(0,sms[i].getOriginatingAddress());
           message_array.add(0,sms[i].getMessageBody());

           com.test.ListActivityClass.myadapter.notifyDataSetChanged();
       }
}

在我的AndroidManifest.xml中,BroadcastReceiver有IntentFilter“android.provider.Telephony.SMS_RECEIVED”。

我的ListActivityClass扩展了ListActivity,包含一个myadapter,它是一个ArrayAdapter,如:myadapter = new CustomAdapter(this,com.test.SMSBroadcastReceiver.phonenumber_array,com.test.SMSBroadcastReceiver.message_array)

所以我的问题是:我从eclipse发送短信到模拟器。每当myadapter.notifyDataSetChanged();我的BroadcastReceiver在我的应用程序没有运行时被调用(完全停止,没有进程启动,没有活动),我得到一个nullpointer异常。

当我删除myadapter.notifyDataSetChanged();问题消失了。

当应用程序运行时,也没有问题,我的应用程序正确收到新的短信并将其显示在列表中。

所以我的猜测是=当应用程序运行时,BroadcastReceiver可以检测到myadapter,因为应用程序在内存中,因此它可以通知更改。当应用程序没有运行时,它不在内存中,因此BroadcastReceiver无法看到任何myadapter,因此它给出了一个nullpointer异常。这说得通。 所以我试着检查:如果进程在内存中,通知更改,否则,不要通知(因为我的应用程序获取了onCreate()收到的所有短信,所以没有必要。

ActivityManager activityManager = (ActivityManager) context
    .getSystemService(context.ACTIVITY_SERVICE);
    List<RunningAppProcessInfo> runningProcInfo = activityManager
    .getRunningAppProcesses(); for (int i1 = 0; i1 <
    runningProcInfo.size(); i1++) { 

    if (runningProcInfo.get(i1).processName.equals("com.test")) {
            com.test.ListActivityClass.myadapter.notifyDataSetChanged();
    }

但没有改变。当app未运行时,我仍然有一个nullpointer异常。

最糟糕的是,我试图用phonenumber_array.add替换phonenumber_array(0,“somephonenumber”);和message_array.add(0,“somemessage”);即使应用程序关闭,检查BroadcastReceiver是否在后台运行,我的想法是正确的。在空指针异常之后,我启动了应用程序,并且somephonenumber和somemessage都存在。

我想念什么? BroadcastReceiver是在后台运行,还是仅在应用程序启动时运行?怎么了?

2 个答案:

答案 0 :(得分:1)

首先,只要您的流程存在,静态数据成员(以及评论建议的替换,Application)才会生效。 onReceive()完成后,您的流程可能会消失几个小时。

如果你想使用静态数据成员作为缓存,那很好,但是持久的数据需要存在于文件系统(数据库,平面文件等)上。

其次,myadapter不应该是静态数据成员。你正在泄露记忆。

或者:

  • 通过BroadcastReceiver

  • 移动此registerReceiver()以供活动注册
  • BroadcastReceiver发送另一个有序广播,由正在运行的活动(如果它在前台)接收,如this blog post中所述,并在{{3}中进行了演示}}

答案 1 :(得分:0)

您可以创建静态布尔变量onScreen并在true方法中将其设置为onResume,并在false方法中设置为onPause。这是了解应用程序是否在屏幕上的最简单方法