2013-04-28 103 views
3

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

这是我的实际工作线程的样本:

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线程上的消息,然后将消息发送到工作者线程。

我不知道如何做solution1,所以我尝试了解决方案2。我尝试添加一个活套到我的工作线程(跑分),这样一来:

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线程的消息。我希望问题很清楚。建议我最好的解决方案。

+0

始终考虑共享'BlockingQueue'作为线程之间发送消息的机制。 – Gray 2013-04-28 19:02:33

+0

还是没有答案?那么你如何通过'Thread'接收消息呢? – l33t 2016-10-20 00:16:37

回答

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公民。

+0

谢谢@lenik。但是......它应该如何定期做我的东西?与我同时(真)我可以每2秒运行我的行动。我怎样才能在你的解决方案中取得同样的效果此外,我怎么能告诉asyncTask从UI线程接收消息? – Gaucho 2013-04-28 18:37:11

+0

@Gaucho,你可以在'doSomething()'之后放置'postDelayed()',它会被再次调用。在2秒间隔内改变100到2000。 'AsyncTask'不需要任何消息,如果你需要做另一件事情 - 激发另一个'AsyncTask'并忘记它。需要'AsyncTasks'的任何结果 - 使用'AsyncLoaders'或'Observer/Observable'模式在后台数据处理和'Activities'之间进行通信。只是不要使用'while(true){sleep(); } - 这真的很糟糕。 – lenik 2013-04-28 19:19:29

+0

我可以使用不同的方法比while(true),但首先我需要实现UIthread和workerThread之间的双向通信。我忽略了我的问题的最初文本。请再读一遍。 – Gaucho 2013-05-04 08:40:37

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