Android中有点复杂的线程问题

时间:2014-01-10 09:20:31

标签: java android multithreading spring

这可能有点抽象,所以我将尝试简化这一切:

  1. 我运行Android应用程序。
  2. 网络上的每个请求都有一个拦截器(http://docs.spring.io/spring/docs/3.1.4.RELEASE/javadoc-api/org/springframework/http/client/ClientHttpRequestInterceptor.html
  3. 此拦截器检查是否存在互联网连接。
  4. 如果没有连接,它会显示一个带有按钮的微小对话框,“重试”覆盖触发网络操作的活动;同时,线程上的睡眠被激活。
  5. 在重试按下时,它取消睡眠,调用方法intercept。然后回到第1步。
  6. 问题:

    所有网络操作都在后台线程上运行,但是当我显示对话框时,系统会将对话框设置为UIThread。 那么,当“重试”按钮被触发时,Dialog触发的回调方法不再是原始线程。

    那么,如果我回想一下方法intercept,并且仍然没有连接,那么所有网络操作都将在UIThread上进行,那么前面提到的Sleep将从步骤5开始。

    我已经调试了所有内容,我确信我遇到的问题已在上面正确解释,并且与这两个线程有​​关。 第一次调用intercept方法时,代码如下:

    Log.d( "Log", ""+(Looper.myLooper() == Looper.getMainLooper()) );
    

    返回 false

    第二次,它返回 true ,经过几秒钟的睡眠后,Android抱怨“用户界面没有响应”(显然:))。

    我想要什么(或者我认为我这样做)

    • 在第一次调用intercept时,获取主题:

      Looper.myLooper().getThread();
      
    • 在第二次调用时,就像现在“我在”UI线程上一样,以某种方式“发送”第二个调用以在之前的Thread上运行。如果我实现了这一点,我确信一切都会奏效。

    请注意,我不能只创建一个新的后台线程,因为AppFlow会继续。

    所以整体问题是:

    从现有主题中,我可以检索它并使用它来运行其他代码吗?

    希望我已经解释过了。

    随意问。

    感谢。

2 个答案:

答案 0 :(得分:1)

要向线程发送消息,经典方法是使用某种线程安全队列(经常使用阻塞队列,但在这种情况下你可能不想阻塞,因为线程有其他的东西要做)。

当你到达线程中的适当点时,检查队列,然后处理其中的内容。

当您想要从该线程完成任务时,只需将它们发布到队列中即可。

答案 1 :(得分:0)

最后解决了只是改变方法调用的问题。

之前,在Dialog被接受"之后,我曾经从" UIThread"触发递归调用。所以我现在正在做的是:

  • 睡眠线程(设置hold = true
  • 显示对话框
  • OnOKDialog - >设置hold = false
  • 线程继续并执行递归调用。

所以这样,后台线程执行递归调用,而不是UI线程。

这样更容易。