在ViewPager中使用Otto时数据变得混杂

时间:2015-03-09 11:25:01

标签: android android-fragments android-viewpager otto

当http请求成功时,我正在使用Otto将结果获取到片段。

在我的应用程序中,我有一个viewpager。由于页面非常相似,我在viewpager中使用相同的片段和不同的数据来下载数据。

片段方法看起来像

 @Override
public void onResume() {
    super.onResume();

    MMApp.getBus().register(this);
}


@Override
public void onPause() {
    super.onPause();
    MMApp.getBus().unregister(this);
}

  @Subscribe
public void onHttpResponseReceived(VolleySuccesObject results) {
}

混合的数据,例如第一页的结果显示在第二页 还有谁知道如何解决这个问题

2 个答案:

答案 0 :(得分:1)

这是因为ViewPager因性能原因而保留了多个片段。如果您想知道哪个片段真正可见,您应该覆盖setUserVisibleHint()方法并在那里的总线上注册/取消注册片段。请注意,此方法默认为true。这意味着Android最初不会使用真值来调用它。因此,setUserVisibleHint()中的逻辑必须检查注册状态,并仅在需要时调用register() / unregister()。同样适用于onStop()方法。如果已在setUserVisibleHint()内调用取消注册,则您不需要在onPause()内调用它,否则Otto将抛出异常。

开源TinyBus使用类似Otto的API,并且有一个名为hasRegistered(Object)的特殊方法,专门用于此情况,以检查给定对象是否已注册到总线。

答案 1 :(得分:0)

我遇到了同样的问题。正如@sergej shafarenka所指出的,viewpagers基本上是根据你的viewpager设置(默认为1)预加载一个片段。

您正在为每个片段订阅相同的对象(例如VolleySuccesObject为您的情况)。现在,当您的片段A位于前台时,片段B也会被加载,其生命周期也会被加载,您可以在其中注册您的公共汽车。

此时片段A和B(假设您目前处于片段A)都在收听VolleySuccesObject。

当然,解决方案基于您的用例。我的方案是我根据Person发送id对象的请求。现在我的片段A和B将收到这些Person APerson B,但我的片段都会收到此对象。我得到的Person对象没有给人id,所以这是一个很大的问题,因为我无法找出Person对象的用途。

<强>解决方案: 我为Person对象(PersonResponseWrapper)使用了一个包装器,我的API服务负责返回包含Personid的PersonResponseWrapper。所以在我的@Subscribe上,我有这个代码:

private String mId; //id used for the API call

@Subscribe
public void onPersonReponseReceived(PersonResponseWrapper response) {
   if(mId.equalsIgnoreCase(response.getid()) { //Yup, this the Person object for me. Processing...
        process(response.getPerson());
   }
}

希望这有帮助。这困扰了我好几天!如果有人遇到类似的要求,将回答这篇文章。