【问题标题】:Android: Unable to communicate in the broadcast receiver to MainActivityAndroid:无法在广播接收器中与 MainActivity 通信
【发布时间】:2016-11-06 16:46:46
【问题描述】:

我正在研究广播接收器。我的代码如下:

Settings2

public void set_notification_task()
    {
        Utilities.initParse(Settings2.this);
        get_notification_info();
    }

    public void get_notification_info()
    {
        ...
    }

    private void setAlarm_manager(Calendar c)
    {
        Intent intent = new Intent(Settings2.this, AlarmBroadcastReceiver.class);   
        PendingIntent pendingIntent = PendingIntent.getBroadcast(Settings2.this, ALARM_RUEST, intent, 0);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
    } 
}

`AlarmBroadcastReceiver

public class AlarmBroadcastReceiver extends BroadcastReceiver {
    final public static String ONE_TIME = "onetime";
    SharedPreferences settings;
    Settings2 setting_activity;

    public AlarmBroadcastReceiver() { }

    public AlarmBroadcastReceiver(Settings2 setting_Context){
        setting_activity =setting_Context;
    }

     @Override
     public void onReceive(Context context, Intent intent) 
     {
         PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG");
         //Acquire the lock
         wl.acquire();

         //You can do the processing here.
         Bundle extras = intent.getExtras();
         StringBuilder msgStr = new StringBuilder();

         if(extras != null && extras.getBoolean(ONE_TIME, Boolean.FALSE)){
          //Make sure this intent has been sent by the one-time timer button.
          msgStr.append("One time Timer : ");
         }
         Format formatter = new SimpleDateFormat("hh:mm:ss a");
         msgStr.append(formatter.format(new Date()));

         Toast.makeText(context, "hello", Toast.LENGTH_LONG).show();
         wl.release();  //Release the lock

         setting_activity.set_notification_task(); //line 49
     }
}

Logcat:

11-07 00:28:02.514: E/AndroidRuntime(25045): FATAL EXCEPTION: main
11-07 00:28:02.514: E/AndroidRuntime(25045): Process: com.abc.wmn, PID: 25045
11-07 00:28:02.514: E/AndroidRuntime(25045): java.lang.RuntimeException: Unable to start receiver com.abc.utilities.AlarmBroadcastReceiver: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.abc.wmn.Settings2.set_notification_task()' on a null object reference
11-07 00:28:02.514: E/AndroidRuntime(25045):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2739)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at android.app.ActivityThread.access$1800(ActivityThread.java:153)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at android.os.Handler.dispatchMessage(Handler.java:102)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at android.os.Looper.loop(Looper.java:148)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at android.app.ActivityThread.main(ActivityThread.java:5438)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at java.lang.reflect.Method.invoke(Native Method)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
11-07 00:28:02.514: E/AndroidRuntime(25045): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.abc.wmn.Settings2.set_notification_task()' on a null object reference
11-07 00:28:02.514: E/AndroidRuntime(25045):    at com.abc.utilities.AlarmBroadcastReceiver.onReceive(AlarmBroadcastReceiver.java:49)
11-07 00:28:02.514: E/AndroidRuntime(25045):    at android.app.ActivityThread.handleReceiver(ActivityThread.java:2732)
11-07 00:28:02.514: E/AndroidRuntime(25045):    ... 8 more

问题:

得到了上面的logcat问题:java.lang.RuntimeException: Unable to start receiver com.abc.utilities.AlarmBroadcastReceiver: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.abc.wmn.Settings2.set_notification_task()' on a null object reference,怎么解决?

谢谢!

【问题讨论】:

  • AlarmBroadcastReceiver 在哪里构建?你能把那个代码贴出来吗?
  • 感谢您的回复。代码已更新。

标签: android broadcastreceiver android-context


【解决方案1】:

这里的问题是setting_activitynull,这里:

setting_activity.set_notification_task();

这是因为设置setting_activityAlarmBroadcastReceiver 构造函数永远不会被调用。由于PendingIntent 用于调用您的广播,它将是AlarmBroadcastReceiver 的默认构造函数,而不是您的自定义构造函数,它在发送广播时被调用。因此,setting_activity 变量永远不会被初始化,因此NullPointerException

【讨论】:

    【解决方案2】:

    我已解决如下:

    public class AlarmBroadcastReceiver extends BroadcastReceiver {
        final public static String ONE_TIME = "onetime";
        SharedPreferences settings;
        Settings2 setting_activity;
    
        public AlarmBroadcastReceiver() { }
    
        public AlarmBroadcastReceiver(Settings2 setting_Context){
            setting_activity =setting_Context;
        }
    
         @Override
         public void onReceive(Context context, Intent intent) 
         {
             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
             PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "YOUR TAG");
             //Acquire the lock
             wl.acquire();
    
             //You can do the processing here.
             Bundle extras = intent.getExtras();
             StringBuilder msgStr = new StringBuilder();
    
             if(extras != null && extras.getBoolean(ONE_TIME, Boolean.FALSE)){
              //Make sure this intent has been sent by the one-time timer button.
              msgStr.append("One time Timer : ");
             }
             Format formatter = new SimpleDateFormat("hh:mm:ss a");
             msgStr.append(formatter.format(new Date()));
    
             Toast.makeText(context, "hello", Toast.LENGTH_LONG).show();
             wl.release();  //Release the lock
    
             setting_activity = new Settings2();
             setting_activity.set_notification_task();
         }
    }
    

    【讨论】:

      【解决方案3】:

      正如 Pathfinderelite 所说,您不能只从接收器访问您的活动。您可以做的是通过依赖注入使您的活动在接收器中可用,或者更简单地,通过在活动中创建指向自身实例的静态链接。 Receiver 然后可以获取实例,但它确实需要检查 null,因为不能保证 Activity 可用并且在调用 onReceive 时不为 null。 (我很抱歉没有格式化,键盘反引号坏了)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多