草庐IT

android - 广播延迟

coder 2023-11-21 原文

我们使用广播来传达远程服务和我们的 UI 之间的状态变化。这样做,我们发现了一个非常奇怪的行为:有时(我找不到任何线索为什么)这些广播会延迟大约 8 秒。

我们如何发送它们(非常基本,mState 只是一个枚举)(服务中的远程进程):

Intent intent = new Intent();
intent.setAction(ACTION_STATE_CHANGED);
intent.putExtra(EXTRA_STATE, mState);

Service.get().sendBroadcast(intent, null);

静态接收器是如何注册的(App):

<receiver android:name=".ServiceStateReceiver">
    <intent-filter>
        <action android:name="service.intent.action.STATE_CHANGE" />
    </intent-filter>
</receiver>

接收类(App):

public class ServiceStateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v("State", "State via static received");
    }
}

现在有时会延迟(总是针对相同的状态)

状态枚举:

public enum State {
    DISCONNECTED,
    BT_DISABLED,
    BT_SCANNING,
    BT_TIMEOUT,
    BT_FAILURE,
    BT_LOCATION_NEEDED,
    CONNECTING,
    ACTIVATION_FAILURE,
    VIN_NEEDED,
    CAR_MODEL_NEEDED,
    MILEAGE_NEEDED,
    READY,
    IGNITION_OFF,
    IGNITION_ON;

    @Override
    public String toString() {
        return name();
    }
}

现在奇怪的部分来了:如果我注册一个动态接收器,我们总是在那里立即收到所有广播。静态的仍然有很大的延迟。如果我通过 sendOrderedBroadcast 发送广播(静态和动态)都有这个延迟。

动态接收器:

registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.i("State", "State via dynamic received");
            }
        }, new IntentFilter(State.ACTION_STATE_CHANGED));

到目前为止我尝试了什么:

  • 从主线程/工作线程发送广播(没有改变)
  • 使用权限属性(没有改变)
  • 连续多次发送广播(不改变任何东西,现在只是得到多个延迟广播)

此外:logcat 没有似乎相关的输出。在不同的设备(OnePlus 3 7.1.1、Z3 6.0.1、S7 Edge 7.1.1)上试过,都表现出相同的行为

我认为这可能是相关的:Android network state change detection takes time

最佳答案

在搜索了几个小时的答案后,我找到了?发布后的解决方案。

似乎向 Intent 添加 FLAG_RECEIVER_FOREGROUND 标志可以完全消除这种延迟。仍然很高兴知道为什么会发生这种情况,以及这是否是一个好的“修复”或者我是否用它破坏了其他东西。

这就是诀窍:

    intent.setFlags(FLAG_RECEIVER_FOREGROUND);

If set, when sending a broadcast the recipient is allowed to run at foreground priority, with a shorter timeout interval. During normal broadcasts the receivers are not automatically hoisted out of the background priority class.

来源: https://developer.android.com/reference/android/content/Intent.html#FLAG_RECEIVER_FOREGROUND

关于android - 广播延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44516173/

有关android - 广播延迟的更多相关文章

  1. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  2. ruby-on-rails - 在所有延迟的作业之前 Hook - 2

    是否可以在所有delayed_job任务之前运行一个方法?基本上,我们试图确保每个运行delayed_job的服务器都有我们代码的最新实例,所以我们想运行一个方法来在每个作业运行之前检查它。(我们已经有了“check”方法并在别处使用它。问题只是关于如何从delayed_job中调用它。) 最佳答案 现在有一种官方方法可以通过插件来做到这一点。这篇博文通过示例清楚地描述了如何执行此操作http://www.salsify.com/blog/delayed-jobs-callbacks-and-hooks-in-rails(本文中描述

  3. ruby - Heroku - 如何开始工作人员(延迟工作)? - 2

    我有一些使用delayed_job的小程序。在我的本地主机上一切正常,但是当我将我的应用程序部署到Heroku并单击应该由delayed_job执行的链接时,没有任何反应,“任务”只是保存到表delayed_job中。Inthisarticleonherokublog写入时,执行delayed_job表中的任务,当运行此命令时rakejobs:work。但是我怎样才能运行这个命令呢?命令应该放在哪里?在代码中,还是从终端控制台? 最佳答案 如果您正在运行Cedar堆栈,请从终端控制台运行以下命令:herokurunrakejobs:

  4. ruby-on-rails - 成功发送延迟作业电子邮件后更新用户表 - 2

    我是一个尝试使用delayed_job的NOOB。我想在使用延迟作业成功发送邮件后更新用户模型。发送邮件:UserMailer.delay.welcome_email(user)如果邮件发送成功,请执行以下操作:User.update_attributes(:emailed=>true)邮件发送成功后如何回调或触发? 最佳答案 您需要创建一个Job对象而不是调用#delay帮助程序。您可以使用successHook来执行回调。classWelcomeEmailJob 关于ruby-on-

  5. ruby-on-rails - 启动同一作业的多个延迟作业进程 - 2

    我在运行多个工作器的设置中使用延迟作业。就我的问题而言,这并不重要,但假设我有10个worker(目前在开发模式下这样做)。我遇到的问题是两个不同的工作人员有时会开始处理同一个工作,调用我的工作对象的perform方法。据我所知,DelayedJob正在使用悲观锁定来防止这种情况发生,但有时它似乎仍然有足够的时间在第一个worker有时间实际锁定它之前锁定它。我只是想看看有没有其他人遇到过这个问题,或者是我的设置有问题。我正在使用Postrgres,这发生在我的开发机器和我托管它的Heroku上。我会尝试在我的工作中解决这个问题,但发生这种情况仍然有点问题。理想情况下,延迟作业永远不会

  6. ruby - 延迟作业每次引发错误时都会创建空气制动器 - 2

    defperformrefund_log={success:refund_retry.success?,amount:refund_amount,action:"refund"}ifrefund_retry.success?refund_log[:reference]=refund_retry.transaction.idrefund_log[:message]=refund_retry.transaction.statuselserefund_log[:message]=refund_retry.messagerefund_log[:params]={}refund_retry.er

  7. ruby-on-rails - 定期延迟工作 - 2

    我正在使用DelayedJob来管理后台工作。但是我有一些任务需要定期执行。例如每小时、每天或每周。现在,当我执行任务时,我会创建一个新任务,在一天/一周/一个月内执行。不过我不是很喜欢。如果由于任何原因,任务没有完全执行,我们不会创建下一个任务,我们可能会失去任务的执行。您如何在Rails应用程序中管理此类事情(延迟作业)以确保您的常规任务列表保持正确? 最佳答案 如果你可以访问Cron,我强烈推荐Wheneverhttp://github.com/javan/whenever您指定要运行什么以及在简单的ruby​​中以什么频率运

  8. iphone - 扩展 restful_authentication/AuthLogic 以支持匿名 iPhone 的延迟登录的最佳方法是什么? - 2

    我正在构建一个与RubyonRails后端对话的iPhone应用程序。RubyonRails应用程序还将为Web用户提供服务。restful_authentication插件是提供快速和可定制的用户身份验证的绝佳方式。但是,我希望iPhone应用程序的用户在新列中存储一个由手机的唯一标识符([[UIDevicedevice]uniqueIdentifier])自动创建的帐户。稍后,当用户准备好创建用户名/密码时,帐户将更新为包含用户名和密码,iPhone唯一标识符保持不变。用户在设置用户名/密码之前不能访问该网站。然而,他们可以使用iPhone应用程序,因为该应用程序可以使用它的标识符

  9. Android Studio开发之使用内容组件Content获取通讯信息讲解及实战(附源码 包括添加手机联系人和发短信) - 2

    运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid

  10. Android 10.0 设置默认launcher后安装另外launcher后默认Launcher失效的功能修复 - 2

    1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La

随机推荐