簡體   English   中英

當我的應用程序未運行時(僅在未運行時),為什么我的BroadcastReceiver給我一個nullpointer異常?

[英]When my app is not running (only when not running), why does my BroadcastReceiver give me a nullpointer exception?

我將嘗試總結一下,因為我的原始代碼很長。 假設我的廣播接收器是這樣的:

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();
    }

但是什么都沒有改變。 應用未運行時,我仍然存在nullpointer異常。

最糟糕的是,我試圖用phonenumber_array.add(0,“ somephonenumber”);替換phonenumber_array; 和message_array.add(0,“ somemessage”); 檢查即使應用已關閉,BroadcastReceiver是否在后台運行,我的想法是正確的。 在出現空指針異常之后,我啟動了該應用程序,並且同時存在somephonenumber和somemessage。

我想念什么? BroadcastReceiver是在后台運行還是僅在應用程序啟動時運行? 怎么了?

首先,靜態數據成員(以及帶注釋的替代項Application )僅在您的流程有效期內存在。 onReceive()完成后,您的過程可能會消失onReceive()微秒。

如果要使用靜態數據成員作為緩存,那很好,但是持久數據需要存在於文件系統(數據庫,平面文件等)上。

其次, myadapter不應是靜態數據成員。 您正在泄漏內存。

要么:

  • 通過registerReceiver()將此BroadcastReceiver移動到活動要注冊的位置,或者

  • 讓此BroadcastReceiver發送另一個有序廣播,以供正在運行的活動(如果它在前台)進行接聽,如本博客文章中所述,並在本示例項目中進行了演示

您可以創建靜態布爾變量onScreen ,並將其設置為trueonResume方法,並設置為falseonPause方法。 這是了解應用程序是否在屏幕上的最簡單方法

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM