【问题标题】:android send message to worker threadandroid向工作线程发送消息
【发布时间】:2013-04-28 15:54:40
【问题描述】:

我有一个线程,我需要定期执行一些检查,从 Web 获取文件,并将消息发送到主 UI 线程。我什至需要在工作线程的每个循环上使用 UI 线程参数(如地图可见区域)。所以我想我需要实现UIthread和workerThread之间的双向通信。 另一个问题是我需要保存添加到地图的每个标记的标识符。我想将 map.addMarker 的结果保存在存储在工作线程中的自定义数组中。这意味着从我更新地图的 uithread 中,我应该告诉 workerThread 更新标记数组..

这是我实际工作线程的示例:

 class MyThread extends Thread {
     private Handler handler;
     private  MainActivity main;

     public MyThread (MainActivity mainClass, Handler handlerClass) {
         this.main=mainClass;
         this.handler = handlerClass;   
     }

     @Override
     public void run(){
            while(true){
               sleep(2000);
               //do my stuffs
               //....
               //prepare a message for the UI thread
               Message msg = handler.obtainMessage();
               msg.obj= //here i put my object or i can even use a bundle
               handler.sendMessage(msg); //with this i send a message to my UI thread

            }
     }
 }

我的实际问题是,当 UI 线程结束处理从工作线程接收到的消息时,我应该对工作线程执行操作。

我想到了 2 个解决方案:

1) 在工作线程上等待,直到 UI 线程处理完消息

2) 在 UI 线程上处理消息,然后向工作线程发送消息。

我不知道如何做解决方案1,所以我尝试了解决方案2。我尝试通过这种方式向我的工作线程(RUN sub)添加一个looper:

 class MyThread extends Thread {
     private Handler handler;
     private  MainActivity main;

     public MyThread (MainActivity mainClass, Handler handlerClass) {
         this.main=mainClass;
         this.handler = handlerClass;   
     }

     @Override
     public void run(){
            Looper.prepare();
            mHandler = new Handler() {
                 public void handleMessage(Message msg) {
                      // Act on the message received from my UI thread doing my stuff
                 }
            };
            Looper.loop();
            while(true){
               sleep(2000);
               //do my stuffs
               //....
               //prepare a message for the UI thread
               Message msg = handler.obtainMessage();
               msg.obj= //here i put my object or i can even use a bundle
               handler.sendMessage(msg); //with this i send a message to my UI thread

            }
     }
 }

问题是 Looper.loop() 之后没有执行任何代码行。我读到这是正常的。我阅读了很多文章,但我不明白我应该如何允许执行我的 while 循环,同时处理来自我的 UI 线程的消息。 我希望问题很清楚。建议我最好的解决方案。

【问题讨论】:

  • 始终将共享的BlockingQueue 视为在线程之间发送消息的机制。
  • 还是没有答案?那么如何在Thread 中接收消息?

标签: android multithreading thread-safety


【解决方案1】:

不要这样做:

while(true){
    sleep(2000);

在很多层面上都非常糟糕。如果您需要一些后台处理,请使用AsyncTasks,如果您需要重复事件,请使用:

private Handler mHandler = new Handler();

private Runnable mSomeTask = new Runnable() {
    public void run() {
        doSomething();
    }
};

然后在代码中的某处:

mHandler.postDelayed(mSomeTask, 100);

这将使您的程序运行得更快,占用更少的资源,基本上成为一个更好的 Android 公民。

【讨论】:

  • 谢谢@lenik。但是..它应该如何定期做我的事情?使用我的 while(true),我可以每 2 秒执行一次操作。我怎样才能在您的解决方案中达到同样的效果?此外,我如何告诉 asyncTask 从 UI 线程接收消息?
  • @Gaucho 你可以把postDelayed()放在doSomething()之后,它会被再次调用。以 2 秒的间隔将 100 更改为 2000。 AsyncTask 不需要任何消息,如果您需要做另一件事 - 再解雇一个 AsyncTask 并忘记它。需要来自AsyncTasks 的任何结果——使用AsyncLoadersObserver/Observable 模式在后台数据处理和Activities 之间进行通信。只是不要使用while(true) { sleep(); }——这真的很糟糕。
  • 我可以使用不同于 while(true) 的方法,但首先我需要实现 UIthread 和 workerThread 之间的双向通信。我对我的问题的初始文本进行了修改。请再读一遍。
【解决方案2】:

我意识到这是一个非常古老的问题,但是对于定期任务调度,请使用以下代码:

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> periodicTask = scheduledThreadPool.scheduleAtFixedRate(new Runnable() {

    @Override
    public void run() {
        // do some magic stuff here
        // note however, that you're running in background!
        Log.d("PeriodicTask", "Doing something....");
    }
}, 0 /* initial delay */, 10 /* start every 10 seconds */, TimeUnit.SECONDS);

当你需要停止周期性任务时,只需发出

periodicTask.cancel(true);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多