【问题标题】:Pass data from broadcast receiver to activity将数据从广播接收器传递到活动
【发布时间】:2012-10-10 00:00:54
【问题描述】:

我有一个正在监听 WifiManager.SCAN_RESULTS_AVAILABLE_ACTION 的广播接收器。 在该接收器中,我过滤所有可用网络并返回具有特定 SSID 的网络列表。我需要将该列表传递回我的应用程序的 MainActivity。 我知道我可以为我的广播接收器创建一个内部类,但我更喜欢创建一个单独的类以便更好地组织。

我正在考虑在我的 mainActivity 类中创建一个静态变量,然后设置该值。 这是一个好习惯吗?

【问题讨论】:

  • 您的接收器代码是使用 registerReceiver 创建的还是使用 条目创建的清单?

标签: android android-activity broadcastreceiver communication


【解决方案1】:

共享和访问跨 Activites 和其他类的信息的一种好方法是使用应用程序对象。只要您有应用程序上下文,您就可以从所有类访问应用程序对象。

请参阅本教程关于应用程序对象:How to use application object

活动中的使用情况:

MyApplicationObject app = (MyApplicationOjbject)getApplicationContext();

app.setMyVariable(变量);

来自活动之外的其他类

MyApplicationObject app = (MyApplicationOjbject)context.getApplicationContext();
app.setMyVariable(variable);

【讨论】:

  • 有趣。我会调查的。
  • Dianne Hackborn,Android 工程师女神不同意这一点。 stackoverflow.com/questions/3826905/…
  • @pcans 我不确定是否真的不同意,她只是说“单身很好(如果使用正确的话)”。
【解决方案2】:

如果你从接收方启动一个主活动,然后你可以使用 putextra() 传递列表,然后你可以在主活动中获取它。

类似的东西。

Intent 意图 = new Intent(ctx.getApplicationContext(), targetActivity); intent.putCharSequenceArrayListExtra(name, value);

【讨论】:

    【解决方案3】:

    我成功地使用了相同的技术。有一次让我感到痛苦的是,当我没有考虑到用户可以倾斜屏幕并重新创建活动时。我没有检查静态变量是否已经设置并反复替换它。请注意这一点。

    我能想到的另一种技术是在活动和广播接收器之间共享回调。接收者调用回调,该回调存储对正确活动的引用并调用 runOnUiThread(action) 以进行 UI 更新。引用应该更新 onStart() 和 onStop()。我从来没有真正使用过这种模式。洗澡的时候想了想:)

    【讨论】:

      【解决方案4】:

      我建议不要使用静态变量来传递信息。如果您的主要活动是从接收者接收信息的唯一对象,则将 BroadcastReceiver 设为主要活动的本地对象。这样做会将那些共同承担责任的元素分组。

      【讨论】:

        【解决方案5】:

        Stefan 是对的,这个静态链接不漂亮。您有时可以拥有同一活动的多个实例(重新创建时,直到垃圾收集器收集它)。或发生多个广播,覆盖您的静态变量值。

        如果您不想使用匿名内部类,您可以重写构造函数并传递对当前活动的引用,您将能够在处理onReceive() 时使用该引用发送结果。完成后只需清理此引用以避免泄露您的活动。

        【讨论】:

          【解决方案6】:

          这就是我从广播中获取数据的方式,代码稍微多一点,但阅读起来更简单 为将来,以防复杂的事情开始。

          Intent intent = new Intent(context, BroadcastReciever.class);
          SimpleResultReciever resultReciever = new SimpleResultReciever(new Handler())
                   .setCallback(new OnLocationCallback() {
                       @Override
                       public void onRecieverLocation(Location location) {
                            if(location != null) {
                                  MainActivity.this.location = location;
                             }
                       }
                   });
          intent.putExtra(SimpleResultReciever.KEY_RESULT_RECIEVER, resultReciever);
          //call intent or create pending intent you will use broadcast stuff.
          
          
          public class SimpleResultReciever extends ResultReceiver {
          
              public final static String KEY_RESULT_RECIEVER = "bundle.broadcast.reciever.callback";
          
              private OnLocationCallback callback;
          
              public LocationResultReciever setCallback(OnLocationCallback callback) {
                  this.callback = callback;
                  return this;
              }
          
              /**
               * Create a new ResultReceive to receive results.  Your
               * {@link #onReceiveResult} method will be called from the thread running
               * <var>handler</var> if given, or from an arbitrary thread if null.
               *
               * @param handler
               */
              public LocationResultReciever(Handler handler) {
                  super(handler);
              }
          
              @Override
              protected void onReceiveResult(int resultCode, Bundle resultData) {
                  super.onReceiveResult(resultCode, resultData);
                  Location location = resultData.getParcelable(LocationManager.KEY_LOCATION_CHANGED);
                  if(callback != null) {
                      callback.onRecieverLocation(location);
                  }
              }
          }
          
          
          
          public class LocationBroadcastReciever extends BroadcastReceiver {
          
              public LocationBroadcastReciever() {
                  super();
              }
          
              @Override
              public void onReceive(Context context, Intent intent) {
                  Bundle extra = intent.getExtras();
                  Location location = extra.getParcelable(LocationManager.KEY_LOCATION_CHANGED);
                  ResultReceiver res = extra.getParcelable(LocationResultReciever.KEY_RESULT_RECIEVER);
                  if(res != null) {
                      Bundle data = new Bundle();
                      data.putParcelable(LocationManager.KEY_LOCATION_CHANGED, location);
                      res.send(Activity.RESULT_OK, data);
                  }
              }
          }
          

          【讨论】:

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