【问题标题】:Retrieving calling context in a BroadcastReceiver()在 BroadcastReceiver() 中检索调用上下文
【发布时间】:2013-01-17 21:14:28
【问题描述】:

我正在尝试显示来自广播接收器的警报对话框片段,但接收器不在将显示片段的活动中(接收器处理此事件上的所有错误广播,无论它是否是活动活动)。

这是我目前的接收器:

private BroadcastReceiver mHttpPostReceiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) { 
              if (intent.getStringExtra("Error") != null) { // error occurred
                      // called from a fragment in another activity
                      NetworkError.show(((Activity) context).getFragmentManager(), error);
               }
      }
};        

但函数中的上下文参数是它所在的活动的当前上下文,并且由于该活动不在屏幕上,因此会导致运行时非法状态异常。有没有办法像通过广播一样发送调用函数的上下文?或者我应该以其他方式实现它吗?

我目前得到的具体错误是:

java.lang.IllegalStateException: onSaveInstanceState 后无法执行此操作

【问题讨论】:

    标签: java android broadcastreceiver android-alertdialog android-context


    【解决方案1】:

    您应该添加额外内容,说明您正在广播的Intent 中的呼叫Activity,然后基于此,写入类似SharedPreferences 的内容。然后在 Activity 的onResume() 中,检查首选项的键是否包含消息,然后更新 UI。

    例如

    @Override
    public void onReceive(Context context, Intent intent) { 
      if (intent.getStringExtra("Error") != null) { 
        String callingActivity = intent.getStringExtra ("CallingActivity");
        if (callingActivity != null);
        context.getSharedPreferences (callingActivity, Context.MODE_PRIVATE).edit().putString ("errorMessage", "You have an error").commit();
      }
    }
    

    然后在每个Activity的onResume()

    @Override
     protected void onResume()
    {
      super.onResume();
      String errorMsg =context.getSharedPreferences ("ThisActivityName", Context.MODE_PRIVATE).getString ("error");
      if (errorMsg.equals ("You have an error")){
        //update fragment code here.  
        //set SharedPreference errorMessage key to hold something else.
      } 
    }
    

    按照我的方式,每个 Activity 都有自己的 SharedPreferences 数据库,数据库名称与 callingActivity 相同。这意味着当你从 onResume() 读入时,"ThisActivityName" 应该是与callingActivity 相同的字符串。但这是主要思想,你可以修改它。

    【讨论】:

    • 这会起作用,但调用这个的活动不会暂停。调用活动发送广播然后空闲,上面的方法现在创建一个 SharedPreferences 条目,但调用函数之后没有到达 onResume 方法。
    • @user1988523 你说的 idles 是什么意思?你的意思是没有调用Activity的onPause()
    • 好像是这样。我在调用函数的 onPause() 和 onResume() 中设置了断点,但它们从未到达。在此期间,调用片段创建一个线程,该线程发送广播,然后由上面的函数在另一个活动中接收(原始片段在发送广播后什么都不做)。
    • @user1988523 不明白为什么Activity不会暂停,但是Fragments也有onPause()/Resume(),你可以试试这个方法。
    • 抱歉耽搁了,但这不是项目中的高优先级问题。您的答案有效,但由于在屏幕变黑之前从未调用过 onPause(),因此我创建了用于错误处理的广播接收器,该错误处理需要在每个活动中使用对话框,并使用 SharedPreferences 来确定活动“可见性”确定哪个活动应该处理错误。感谢您的洞察力。由于此应用程序主要使用片段和少量活动,因此这是一种可接受的解决方法。
    【解决方案2】:

    我在 onReceive 方法中做了这样的事情:

        if (context instanceof LoginActivity) {
            switchLoginFields((LoginActivity) context, isConnected);
        } else if (context instanceof ReceiptActivity || context instanceof AmountActivity) {
            showArelt(context, isConnected);
        }
    

    【讨论】:

    • 我需要使用广播发送者的上下文,而不是上面函数中的上下文(尽管一旦我有了它就会很有用)。
    猜你喜欢
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 2017-09-16
    相关资源
    最近更新 更多