Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 从服务到UI层的同步消息_Android_Android Intent_Android Service - Fatal编程技术网

Android 从服务到UI层的同步消息

Android 从服务到UI层的同步消息,android,android-intent,android-service,Android,Android Intent,Android Service,广播意图的顺序是否得到保证?就是说,如果我这样做了, sendBroadcast(intent1); sendBroadcast(intent2); 接收器是否保证在intent2之前获得intent1?我怀疑答案是否定的,但在这种情况下,我不太确定如何解决我的问题 我正在尝试为我的应用程序创建一个“忙碌”指示器,当设备在网络上通话时显示忙碌,然后在网络通信结束时消失。所有网络通信都发生在意图服务中 我的尝试是在服务中开始网络通信时发送一个忙碌的开始意图,在网络通信结束时发送一个忙碌的停止。这

广播意图的顺序是否得到保证?就是说,如果我这样做了,

sendBroadcast(intent1);
sendBroadcast(intent2);
接收器是否保证在intent2之前获得intent1?我怀疑答案是否定的,但在这种情况下,我不太确定如何解决我的问题

我正在尝试为我的应用程序创建一个“忙碌”指示器,当设备在网络上通话时显示忙碌,然后在网络通信结束时消失。所有网络通信都发生在意图服务中

我的尝试是在服务中开始网络通信时发送一个忙碌的开始意图,在网络通信结束时发送一个忙碌的停止。这似乎大部分是有效的,但我偶尔会发现我收到的停止和开始信息的顺序

有没有更好的办法来解决这个问题


我正在考虑为每个忙碌的意图添加一个ID,这样它们就可以配对了。这样,如果我收到一个开始,而我已经收到一个停止,我可以忽略它。或者,更简单地说,在每个广播中添加一个整数序列号。如果我接收到的广播当前意图的顺序小于上次接收到的意图的顺序,请忽略它。

您是否考虑过使用
处理程序
对象从
IntentService
中的后台线程进行通信?与
broadcastReceiver
方法相比,处理程序的优势在于,处理程序使用消息队列对消息对象进行排序


(我假设您的服务与应用程序的主线程处于相同的过程中)。

回答我自己的问题

意图的至少一个可行替代方案是通过应用程序类执行消息传递,即

  • 创建侦听器接口
  • 管理应用程序中侦听器对象的集合/提供添加/删除侦听器的方法
  • 感兴趣的实体调用应用程序方法来添加/删除自己作为侦听器
  • 在应用程序中添加“notify”方法,在每个注册的侦听器上调用相应的侦听器接口方法
  • 服务调用应用程序的通知方法来
  • 比如说,

    public class MyApplication extends Application {
      public interface MyListener {
        void onEvent();
      }
    
      private Set<MyListener> listeners = new HashSet<Listener>();
    
      public void addListener(MyListener l) {
        listeners.add(l);
      }
    
      public void removeListener(MyListener l) {
        listeners.remove(l);
      }
    
      public void sendEvent() {
        for (MyListener l: listeners) { l.onEvent(); }
      }
    }
    
    为您服务

    ((MyApplication)getApplication()).sendEvent();
    

    这在不使用意图或静态变量的情况下提供同步消息传递。

    我正在尝试从意图服务到UI线程进行通信。是的。处理程序应该这样做。或者我遗漏了什么?在这种情况下,您需要在活动中构造处理程序,并为服务提供对它的引用。如何做到这一点?简单的答案是将其存储在某个静态变量中。您可以查看谷歌的应用内计费示例代码。他们的代码有点过度设计,但基本上他们的服务调用helper对象上的静态方法,该对象最终持有对Handler对象的静态引用。或者,如果您不喜欢静态(我不喜欢),您可以在应用程序的应用程序对象中存储对它的引用,并让服务从中检索它。如果服务得到一个空处理程序,它将跳过消息传递。我不能接受使用静态字段是组件间消息传递的最佳实践,不管它来自google示例代码。正如您在这里介绍的,看起来它从服务线程直接调用活动的主UI线程。这是一个禁忌。我真的认为如果你想从一个线程调用另一个线程,你需要一个Handler对象。你是对的,它确实需要。假设如果活动在
    onEvent()
    中修改UI线程,则应使用
    runOnUIThread()
    进行修改。如果我们愿意,回调框架可以隐藏这一点,但我宁愿让UI线程来决定是否需要这一额外步骤。你提到的一件好事是,对于那些希望在自己的应用程序中使用你的代码示例的人来说。我不是在这里向大家指出android应用程序开发的每一个细微差别。理解不能从非UI线程更新UI层次结构是一个非常基本的概念。我已经花了相当长的时间回到这里,为我自己的问题写了一个长而详细的答案。不客气。如果你有问题,我建议你投票删除这个问题。
    ((MyApplication)getApplication()).sendEvent();