首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Android

Android 线程里发送广播必须等线程结束才能收到广播?

  •  
  •   doublemark · 18 天前 · 1335 次点击

    原谅我是一个硬件工程师,最近在做一个和硬件相关的测试软件,大部分功能都已实现,目前问题是: 在 C++里可以在线程里发送指令,然后 sleep 一段时间用以等待返回的数据,而 android 里想用同样的思路: 1、通讯封装在了一个 Service 里保持后台运行; 2、在按钮点击事件里按下按钮后新建 Thread,线程里发送广播到 Service,Service 里根据广播里的参数去执行相应的发送命令,并在 Service 里做接收解析,若解析正确则置一标志位。 3、2 里提到的线程在发送完广播后,sleep 一段时间等待该标志位,若标志位成立则继续往下执行,以此类推。 目前问题就在于: 2 里在 Thread 里发送广播,根据调试以及 log 看,并不是在 sendbraodcast 方法执行后再 receiver 里收到,而是该 Thread 执行完之后才会收到,这样是正常的吗?

    对于这种需要执行多个步骤的耗时和等待操作,在 Android 里有没有好的方案?

    感谢各位,很荣幸能来到这里。

    17 回复  |  直到 2019-02-02 15:21:38 +08:00
        1
    momocraft   18 天前
    (在正确实现的时候)不是

    Java 有比较齐全的线程和同步 API,简单的比如 CountDownLatch / Future
        2
    yippees   17 天前
    1、activity 收发测试是 sendbraodcast 方法执行后 receiver 里收到,再等待结束。
    2、加个接收广播
        3
    doublemark   17 天前
    @yippees 实际使用中确实是在 sendbroadcast 之后在 receiver 里能收到,但是一放到 thread 里
    {
    sendbroadcast(intent);
    try {
    sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    dosomethingA();
    dosomethingB();
    dosomethingC();
    }
    在这里,sendbroadcast 方法执行后并没有收到,反而是 dosomethingC 之后才收到。奇怪啊。
        4
    fuckshiter   17 天前 via iPhone
    发送广播后。接收到广播做一个回调,或者用 eventbus 第三方库
        5
    tempdban   17 天前 via Android
    我跟你说其实安卓的 activity 和 service 默认是跑在一个线程里的
    想这么干你要给 service 新建个线程
    这就是已经熟悉 Unix 变成的人必定踩坑点。
        6
    yukiww233   17 天前
    上 eventbus
        7
    fuckshiter   17 天前 via iPhone
    class FooBroadcastReceiver(var callback: () -> Unit) : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
    when (intent?.action) {
    "XXXXACTION" -> {
    callback();
    }
    }
    }
    }

    var fooBroadcastReceiver: FooBroadcastReceiver? = null
    fun sendCommand(callback: () -> Unit) {
    fooBroadcastReceiver = fooBroadcastReceiver ?: FooBroadcastReceiver(callback)
    fooBroadcastReceiver?.callback = callback
    mContext.sendBroadcast(Intent("XXXXACTION"))
    }
        8
    fuckshiter   17 天前 via iPhone
    @fuckshiter
    使用
    fun send() {
    sendCommand {
    doSomething1();
    doSomething2();
    doSomething3();
    }
    }
        9
    yippees   17 天前
    @doublemark
    我的代码也是 new thread 的
    只是接收也在 activity 就是。

    先打发日志,再打收日志,最后 sleep 结束日志
        10
    richard1122   17 天前
    首先确认一下是真的开了新线程,是 thread.start() 而不是 thread.run() 了,后者会在当前线程直接执行这段代码。
        11
    pagxir   17 天前
    你还是找个搞软件的来弄吧。你这是根本没有理解线程的概念。线程都 sleep 了,自然是不可能在去接收广播。
    receiver 的线程是运行在 handler 所在的线程。
        12
    zpxshl   17 天前 via Android
    不应该出现这种结果。我猜 10 楼说得对,你写成 new thread.run 。(应该调用 start 方法)
    至于楼上一堆说不能 sleep 的人是认真的吗。。。。
        13
    SuperNovaSonic   17 天前
    同意楼上,11 楼上来就乱说,楼主说的是 sleep 又不是让主线程 sleep
        14
    SuperNovaSonic   17 天前
    另外自己亲测了下,没有问题
    2019-02-02 11:19:11.790 14951-15076/com.example.glidetest D/BroadcastReceive Test: new thread sendBroadcast
    2019-02-02 11:19:11.791 14951-15076/com.example.glidetest D/BroadcastReceive Test: new thread try to sleep
    2019-02-02 11:19:11.805 14951-14951/com.example.glidetest D/ BroadcastReceive Test: BroadcastReceiver onReceive
    2019-02-02 11:19:14.793 14951-15076/com.example.glidetest D/BroadcastReceive Test: new thread after sleep
        15
    siyehua   17 天前
    发送广播不要建立线程。广播本身具有跨进程、线程的能力。直接根据需求发送与接收广播即可。使用到线程就必须用到线程消息同步的技术。
        16
    RikkaW   17 天前
    sendBroadcast 实际是“自己的应用进程到 system_server 进程,再到目标进程”这样一个比较重的过程(因为本来就是设计用来跨进程广播的),用在这里就过于夸张了。(所以可能是 sleep 时间太短了正好就看起来更晚收到?)另外发广播并不需要建立线程,因为只有把 intent 发给 system_server 的过程。
    这里的情况看起来只要用 LocalbroadcastManager EventBus 这样的或是绑定服务( https://developer.android.com/guide/components/bound-services )就够了。
        17
    ksssdh123   17 天前
    广播是一个很神奇的组件,跨线程,还跨进程
    如需求是需要跨进程,那就用起来吧
    如果用了 Rxjava,那么 Rxbus 用起来(也可以跨线程),如果没用 Rxjava 就 EventBus 应该满足你的需求了吧
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3766 人在线   最高记录 4385   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 18ms · UTC 09:10 · PVG 17:10 · LAX 01:10 · JFK 04:10
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1