安卓如何向工作线程发送消息

3
我有一个线程,在其中需要定期执行一些检查、从网络获取文件并向主UI线程发送消息。我甚至需要在每个工作线程的循环中使用UI线程参数(如地图可见区域)。因此,我认为我需要在UIThread和WorkerThread之间实现双向通信。
另一个问题是我需要保存添加到地图上的每个标记的标识符。我想将map.addMarker的结果保存在我的自定义数组中,该数组存储在我的worker线程中。这意味着在更新地图的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线程结束处理从工作线程接收的消息时,我应该对工作线程执行一个操作。
我想到了两个解决方案:
1)在工作线程上等待,直到UI线程处理完消息。
2)在UI线程上处理消息,然后向工作线程发送消息。
我不知道如何执行解决方案1,所以我尝试了解决方案2。我尝试将一个looper添加到我的工作线程(RUN子程序)中,方法如下:
 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 视为在线程之间发送消息的机制。 - Gray
还没有答案吗?那么如何在“线程”中接收消息呢? - l33t
2个回答

2

不要这样做:

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
@Gaucho 你可以在 doSomething() 后面加上 postDelayed(),这样它就会再次被调用。将100改为2000以获得2秒的间隔。如果你需要做另一件事情,AsyncTask 不需要任何消息,只需启动另一个 AsyncTask 并忘记它即可。如果你需要从 AsyncTasks 中获取任何结果,请使用 AsyncLoadersObserver/Observable 模式来在后台数据处理和 Activities 之间进行通信。只是不要使用 while(true) { sleep(); } -- 这真的非常糟糕。 - lenik
我可以使用不同的方法来代替 while(true),但首先我需要实现 UI 线程和工作线程之间的双向通信。我更新了我的问题的初始文本,请再次阅读它。 - Gaucho

1

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

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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接