如何将消息从后台服务发布到 UI 片段?

2024-01-21

我有一个问题EventBus来自绿色机器人。

我试图从我的同步适配器的后台服务发布一个事件,并将其捕获在一个片段中以更新 UI。

问题是,当我尝试从同步适配器发布事件时,我在调试日志中收到以下内容:



No subscribers registered for event class olexiimuraviov.ua.simplerssreader.event.UpdateUIEvent
No subscribers registered for event class org.greenrobot.eventbus.NoSubscriberEvent
  

我将片段注册在onResume并将其取消注册onPause

@Override
public void onResume() {
    super.onResume();
    EventBus.getDefault().register(this);
    if (mDebug) Log.d(LOG_TAG, EventBus.getDefault().isRegistered(this) + "");
}

@Override
public void onPause() {
    super.onPause();
    EventBus.getDefault().unregister(this);
}

onResume中的日志语句显示fragment已成功注册。

这是 onEvent 方法:

@Subscribe
public void onEvent(UpdateUIEvent event) {
    if (mSwipeRefreshLayout.isRefreshing())
        mSwipeRefreshLayout.setRefreshing(false);
}

我试图用后台线程模式调用 onEvent 方法,但没有帮助。

之后,我尝试使用处理程序来发布事件,但 eventbus 仍然找不到任何已注册的事件订阅者。

 new Handler(Looper.getMainLooper()).post(new Runnable() {
     @Override
     public void run() {
         EventBus.getDefault().post(new UpdateUIEvent());
     }
 });

这是我的同步适配器的 onPerform 方法:

    @Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
    // Fetch data from server
    } finally {
       // close everything
       new Handler(Looper.getMainLooper()).post(new Runnable() {
           @Override
           public void run() {
               Log.d(LOG_TAG, "Update event");
               EventBus.getDefault().post(new UpdateUIEvent());
           }
       });
    }
}

如何使用 Greenrobot 将事件从同步适配器发送到片段EventBus?


tl;dr

你永远不必担心哪个thread您发布了一个活动,但您必须担心是哪个活动process你发布它来自。您的同步适配器与片段在不同的进程中运行 - EventBus 仅在创建它的进程中工作。

长版

除了订阅事件之外,您永远不需要启动不同的线程,甚至不需要担心您在任何地方使用哪个线程。

check http://greenrobot.org/eventbus/documentation/delivery-threads-threadmode/ http://greenrobot.org/eventbus/documentation/delivery-threads-threadmode/有关更多详细信息,但语法非常不言自明:

@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void thisMethodWillBeRunInABackgroundThread(DoLoginEvent event)
{
    //Run some code that makes an HTTP request
}

并在 UI 上运行一些东西:

@Subscribe(threadMode = ThreadMode.MAIN)
public void thisMethodWillBeRunOnTheUIThread(LoginSuccessfulEvent event)
{
    //Run some code that touches the UI
}

当您调用 post() 来触发两个DoLoginEventLoginSuccessfulEvent你在哪个线程中绝对不重要。

现在,您面临的真正问题是:订阅对象上似乎没有捕获事件。

我怀疑这是因为您的同步适配器在不同的环境中运行Process。 EventBus 仅在以下范围内运行Process它被创建了。

同步适配器(例如 BroadcastReceiver 或服务)在单独的进程中运行,以允许您与服务器同步数据without与您的应用程序本身的任何交互。这个想法是,即使应用程序关闭,您也可以与服务器同步,将所有内容保存到数据库中,然后当应用程序启动时,它会检查该数据库(快速),而不必与服务器同步(慢速)。但是,如果您的应用程序在同步适配器运行时处于活动状态,那么您想要保存到数据库,同时也告诉应用程序有一些新信息,对吧?

因此,为了允许您的同步适配器与您的应用程序进行通信,我建议您在片段/活动中设置一个 BroadcastReceiver,然后从您的同步适配器广播一个意图。

这个机制和EventBus的概念非常相似,你甚至可以发送粘性意图 https://stackoverflow.com/questions/2584497/what-is-the-difference-between-sendstickybroadcast-and-sendbroadcast-in-android!您的片段会监听这些意图,但仅限于它还活着的时候。如果您的同步适配器在应用程序关闭时发送广播,则不会发生任何事情。但是当片段启动并注册这些意图时,它将获得最后一个sticky one.

public class LogFragment extends Fragment {

    private LogReceiver mReceiver;

    public class LogReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //you can call the EventBus from in here
        }
    }


    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mReceiver = new LogReceiver();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        getActivity().registerReceiver(mReceiver, new IntentFilter("com.whatever.whatever"));
        return view;
    }

    @Override
    public void onDestroyView() {
        getActivity().unregisterReceiver(mReceiver);
        super.onDestroy();
    }
}

然后从您的同步适配器

Intent sendIntent = new Intent("com.whatever.whatever");
sendIntent.putExtra("SYNC_ADAPTER_EXTRA", "Your sync adapter says hi");
context.sendBroadcast(sendIntent);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将消息从后台服务发布到 UI 片段? 的相关文章

随机推荐

  • 显示多个图像动画

    我想显示一个背景图像和多个向下移动的图像 就像 降雪 场景一样 我该怎么做 背景图像不应该移动 只有它上面的小图像应该掉落 我该怎么做 更新 gt 我已在屏幕上显示图像 但它们都是同时出现的 但我想显示在不同时间出现的图像 我该怎么做 嘿
  • 如何将数据库从 SQL Server 2005 迁移到 2008?

    我想完全或部分迁移数据库 现在我要做一个完整的数据库 部分将作为单独的问题发布 我正在考虑的策略 复制数据库向导 将 2005 数据库转换为脚本 在 2008 年运行脚本 简单的SQL查询 我的问题 我想使用方法 2 是否可以这样做 如果是
  • 使用 Rcpp 将循环从 R 转换为 C++

    我想使用 Rcpp 提高一些 R 代码的速度 然而我对C 的了解却很少 因此 我检查了 Rcpp 提供的文档 以及 Dirk Eddelbuttel 网站上提供的其他文档 阅读完所有内容后 我尝试执行一个用 R 编写的简单循环 不幸的是 我
  • 如何用Javascript轻松监听xhr请求?

    我正在开发一个 Firefox 扩展 我想知道页面何时发起 xhr 请求 我看到了一些代码 但它们非常大 有没有简单的示例可以实现此目的 我正在测试这段代码 function TracingListener this receivedDat
  • Angular 2如何分别加载2个App根组件

    是否可以加载 2 个不同的根组件 不是在页面中并排 找一个笨蛋的例子 http plnkr co edit XSJ8ac 唯一的区别是两个根组件都加载在单个页面中
  • 有没有一种快速、简单的方法来转储 MacOS X 钥匙串的内容?

    我正在寻找一种方法将 OS X 钥匙串的内容转储 导出 到我可以在其他地方轻松处理的文件中 例如制表符分隔的纯文本或类似的内容 钥匙串访问应用程序不提供任何此类功能 获取钥匙的数据需要依次打开每个钥匙串 并且每次都必须输入钥匙串的密码才能查
  • 占位符文本溢出:省略号在 IE10 中不起作用

    如果占位符中的文本长度较长 我使用下面的代码显示省略号 它在 Chrome 和 Firefox 中运行良好 在 IE 中它不起作用 input placeholder text overflow ellipsis 我遇到了同样的问题并遇到了
  • 如何在 MySQL innoDB 中重建索引并更新统计信息?

    我有使用 MS SQL 服务器的经验 它是可能且有用的 and 重建索引 https msdn microsoft com en us library ms189858 aspx 我在MySQL innoDB中找不到这样的选项 有这样的选项
  • CRAN 提交 - R CMD 检查警告 - 使用编译标志

    我正在尝试将我的第一个包裹提交至CRAN在我的机器上 我在运行时收到以下警告R CMD check via RStudio checking compilation flags used WARNING Compilation used t
  • C# NetCDF 库

    我目前正在从事 或至少正在计划 几个需要处理大量重复数据的项目 这种数据在电子表格或数据库中运行良好 但在 XML 中却很糟糕 NetCDF 似乎是一个不错的文件格式选择 但是 我的工作是使用 C 进行的 并且没有可用的 官方 NetCDF
  • 我可以从 Eclipse 视图中删除重复的运行配置吗?

    我有 Maven 父项目和孩子 当我去运行 gt 运行配置 in Java应用程序我两次看到很少的启动器 唯一的区别是路径Common选项卡 部分另存为 共享文件 我什至无法在不重命名第二个的情况下重命名其中一个 有没有办法至少隐藏两个同名
  • 具有可选参数的方法

    有没有一种方法可以使方法可以接受参数 但也可以在没有参数的情况下调用 在这种情况下 参数被视为nil像下面这样 some func variable some func def some func variable nil end
  • AngularJS 主页的多个 ng-views

    好吧 我是 Angluar 的新手 刚刚开始使用 ngRoute 和 ngView 指令 我遇到了一些对我来说是问题的问题 但我怀疑这只是一个问题 因为我缺乏 Angluar 的经验 我的 index html 页面上有以下标记 简化 di
  • Mercurial MSSCCAPI 提供商?

    有人知道 Mercurial 的 MSSCCAPI 提供商吗 我想使用 PowerBuilder 尝试 Kiln Mercurial 但 PowerBuilder IDE 只识别 MSSCCAPI 提供程序 即not与 MS SCC Pac
  • Microsoft Edge 请求后退/前进按钮上的新页面

    单击后退和前进按钮时 最新版本的 Microsoft Edge 浏览器 41 162 会请求新页面 我在多个平台上测试了多个浏览器 只有 Edge 表现出这种行为 这是一个测试页 http www easynotecards com sta
  • aws sagemaker模型训练中是否有某种持久的本地存储?

    我用aws sagemaker做了一些实验 从S3下载大数据集的时间是非常有问题的 特别是当模型仍处于开发阶段 并且你想要某种相对较快的初始反馈时 是否有某种本地存储或其他方式来加快速度 EDIT我指的是批量训练服务 它允许您以 Docke
  • 为什么 Flask 会话的值必须是 JSON 可序列化的?

    我正在尝试在 Flask 应用程序中为用户会话实例化一个基本模型实例 我对我的类必须是 JSON 可序列化的要求感到措手不及 我认为会话字典只是存储会话信息的任意构造 但听起来它的使用有更多限制 其中之一显然是 JSON 可序列化的值 还有
  • 可继承的版本 Maven 插件规则

    跑步时mvn versions display dependency updates为了版本 Maven 插件 https www mojohaus org versions maven plugin 我看到很多这样的事情 INFO org
  • 角度分量的类型

    我可以将角度组件类称为类型吗 我看到 Ionic 的用途any对于组件 在 Typescript 中是否可以声明一个仅需要组件类的参数类型 我看到了这个问题 但组件在构造函数中没有任何共同点 将类作为参数传递会导致 不可更新 错误 http
  • 如何将消息从后台服务发布到 UI 片段?

    我有一个问题EventBus来自绿色机器人 我试图从我的同步适配器的后台服务发布一个事件 并将其捕获在一个片段中以更新 UI 问题是 当我尝试从同步适配器发布事件时 我在调试日志中收到以下内容 No subscribers register