EventBus:当应用程序在后台时,活动不会收到事件

时间:2016-03-16 10:05:24

标签: android android-fragments service background-process event-bus

我使用EventBusActivityService之间进行通信。 今天我遇到了问题,不知道为什么。

  1. 我有ActivityFragmentService。所有这些都工作正常。

  2. ActivityFragmentregistered他们Receive events Service

  3. ActivityFragment,我un-register时调用了onDestroy()

  4. 在正常情况下,当Services投放events时,FragmentActivity可以收到events并且效果良好。

  5. 但是当App按下background时(按主页或电源按钮),只有Fragment会收到从Service传递的事件,{ {1}}没有收到它们。

  6. 我在ActivityonPause() Activity中都没有做任何事情。

  7. 问题:

    有没有解释?如何在后台推送应用时,如何Fragment收到Activity收到的活动?

5 个答案:

答案 0 :(得分:13)

在EventBus 3.0.0版中,您可以使用Sticky帖子。

这样您就可以并且应该在' onStop()'上取消注册EventBus。防止内存泄漏,并在应用程序到达前台时仍然接收事件。

以这种方式发布活动:

EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));

使用粘性标记订阅事件,如下所示:

@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {   
    textField.setText(event.message);
}

EventBus文档: http://greenrobot.org/eventbus/documentation/configuration/sticky-events/

答案 1 :(得分:12)

当用户按下/ home按钮时,Activity可以随时销毁,因此您无法使用EventBus接收数据。如果在Activity处于后台时您尝试接收数据的方式如何,则可能会泄漏内存,应用程序将崩溃。

当用户恢复Activity时,可以采用其他方法在activity中获取数据。

您可以使用用户sharedpreferences或本地数据库来保存传递的结果service。当用户导航回活动时,请从sharedpreferences或数据库中读取它。

这样就不会出现内存泄漏或数据丢失的问题。

编辑1:

始终建议取消注册onPauseonStop中的侦听器,因为当活动不在前台时,活动不需要这些事件。由于无法保证调用onDestroy(),因此您可以在活动不再打开时继续接收广播。

答案 2 :(得分:3)

当不可见(后台模式)时,Activity类提供两个生命周期方法onStop()和onRestart(),这些方法允许您专门处理活动处理停止和重新启动的方式。与标识部分UI障碍的暂停状态不同,停止状态可确保UI不再可见,并且用户的焦点位于单独的活动(或完全独立的应用程序)中。

为了理解这个循环,请查看此图像,该图像显示应用程序退出前台模式时的流程。

When the user leaves your activity

在您的情况下,您可以像这样处理问题。

  • 使用本地数据库(Sqlite),sharedPreferences为用户提供保存持久应用程序数据的机制。
  • 在onStop()方法上处理数据持久性。
  • 当用户回调您的应用时,您需要使用onRestart()方法恢复数据。

    以下是实施该方法的方法。

    public class Calc extends Activity {
    public static final String PREFS_NAME = "MyPrefsFile";
    
    @Override
    protected void onCreate(Bundle state){
       super.onCreate(state);
       . . .
    
       // Restore preferences
       SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
       boolean silent = settings.getBoolean("silentMode", false);
       setSilent(silent);
    }
    
    @Override
    protected void onStop(){
       super.onStop();
    
      // We need an Editor object to make preference changes.
      // All objects are from android.context.Context
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putBoolean("silentMode", mSilentMode);
    
      // Commit the edits!
      editor.commit();
    }
    

    }

请阅读Android Developer site

中的以下文档

答案 3 :(得分:2)

很难猜出导致此行为的行为,请考虑提供一些代码。

但显而易见的是,你有一些设计缺陷。

当用户从应用程序导航回来时,您必须从您的ui组件(例如“活动”或“片段”)中的任何事件总线或侦听器取消注册,如果您不这样做,则很有可能泄露您的活动和所有资源它持有。

您应该将在后台服务中接收或计算的任何数据存储到文件或数据库中,当用户打开或重新打开您的应用时,您应该检查该数据并对其进行操作。

答案 4 :(得分:2)

需要更多代码或示例来帮助您。但请尝试以下方法。

  1. 您的活动是否从baseActivity扩展?如果是这样,请删除onDestroy eventbus取消注册代码并检查。
  2. 在开发者选项中,检查是否取消选中“不要保留活动”选项。
  3. 如果你已经覆盖了后面的事件,那么按下后面会杀死你的应用程序。