Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android send message to worker thread

I have a thread where I need to periodically perform some checks, get files from the web, and send messages to the main UI thread. I even need to use UI thread parameters (like the map visible area) on each loop of the worker thread. So I suppose that i need to implement bidirectional communication between UIthread and workerThread. Another problem is that I need to save the identifier of each marker added to the map. I want to save the result of map.addMarker inside my custom array stored in my worker thread. this means that from the uithread, where i update the map, i should tell the workerThread to update the array of markers..

This is a sample of my actual worker thread:

 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

            }
     }
 }

My actual problem is that when the UI thread ends processing the message received from the worker thread i should perform an action on the worker thread.

I thought 2 solutions:

1)wait on the worker thread till the message has been processed by the UI thread

2)process the message on the UI thread and then send a message to the worker thread.

I don't know how to do the solution1, so i tried the solution2. I tried adding a looper to my worker thread (RUN sub), this way:

 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

            }
     }
 }

The problem is that after the Looper.loop() no line of code is executed. I read that this is normal. I read many articles but I didn't understand how should I allow the execution of my while loop, and simultaneously process messages coming from my UI thread. I hope the problem is clear. Suggest me the best solution.

like image 303
Gaucho Avatar asked Apr 14 '26 06:04

Gaucho


2 Answers

don't do this:

while(true){
    sleep(2000);

it's awfully bad on so many levels. if you need some background processing, use AsyncTasks, if you need a repeating event, use:

private Handler mHandler = new Handler();

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

and then somewhere in the code:

mHandler.postDelayed(mSomeTask, 100);

this will make your program work faster, jam less resources and basically be a better Android citizen.

like image 130
lenik Avatar answered Apr 16 '26 18:04

lenik


I realize this is a very old question, but for periodic task scheduling, use this code:

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

and when you need to stop the periodic task, just issue

periodicTask.cancel(true);
like image 44
miha Avatar answered Apr 16 '26 18:04

miha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!