0

I'm sure the solution to my problem will be one of those "duh" moments, but I'm stuck so any helpful hints would be gratefully received.

Problem: I have a UI with a background thread. The UI has a start/stop button to initiate and then stop a process in the thread. This is achieved using messages from the UI to the message handler in the thread wrapped in a looper. The thread process is in a while loop dependent on a boolean set true/false by the thread message handler. However, once started, no further messages are processed and the loop continues ad infinitum.

private class MyThread extends Thread{
    public void run() {
      Looper.prepare();
          MyThreadChildHandler = new Handler() {
              public void handleMessage(Message msg) {
                  switch(msg.arg1) {
                 case START:
                          boolLoop = true;
                          doWhileLoop();
                     case STOP:
                          boolLoop = false;
                     }
          };
      Looper.loop();
    }

    private void doWhileLoop(){
        while (boolLoop = true){
            stuff.do
        }
        finish.do
    }

}

I've got a logcat message on the STOP message from the UI and that's firing, but the thread never picks it up because it's stuck in the while loop and the message handler doesn't get a look-in.

Is there a way of letting the thread handler check for messages from within the while loop at various points? Or is there another way of getting a thread based continuous while loop to start and stop based on messages from the UI?

Cheers Andy

1 Answers1

2

Change:

  while (boolLoop = true){
            stuff.do
        }

to:

  while (boolLoop == true){
            stuff.do
        }

or preferrably

  while (booloop){
          stuff.do
        }

You need to check for equality(==) not assign(=).

Also another thing is you don't need a looper object. Just control it with the while loop. I would do it like this:

I would have the thread execute its process indefinitely until it either times out or a message from a handler that controls that thread stops the execution of that thread, via a flag variable that is shared between two classes, like Activity and Thread. Where the activity's state controls the thread. For instance, say the application goes into the background, that's when you would set the running flag to false, so that it stops. Your Looper execution is not necessary. Also the way the messages would be passed is through a handler.

JoxTraex
  • 13,423
  • 6
  • 32
  • 45
  • This is a good recommendation, but I'm not sure it will do the job. OP's real problem, I think, is that `handleMessage` never returns from a `START` message, so the looper never gets to process the next message. – Ted Hopp Apr 09 '13 at 22:02
  • Thanks for the super quick response guys. – Andy Lee Apr 09 '13 at 22:37
  • JoxTraex, = vs == was just a typo in abbreviating my code. I was trying to avoid global variables to provide UI/thread control and use messaging instead. But, this has lead me down my current rabbit hole. Maybe the looper isn't necessary as I don't really need to queue alot of messages, but I still need a way to interrupt the while loop based on a message from the UI. – Andy Lee Apr 09 '13 at 22:44
  • Its not really a rabbit hole, but its a rabbit hole from the way you are approaching it. My approach solves that, and getting around a global variable is not really possible. Or another Approach would be to be to use an Activity and a Service methodogly and have the Activity control that service via bindings. They can message pass directly with each other. – JoxTraex Apr 09 '13 at 22:47
  • Ted Hope, yep, this is the problem. I want to carry on stuff.do(ing) until a stop request is made from the UI. Then Finish.do and finally exit the sub doWhileLoop(). The thread gets stuck in the while loop and never process the incoming message. Can you think of a different way to achieve my end. Ta. – Andy Lee Apr 09 '13 at 22:48
  • Look up the methodology I mentioned about Service and Activity bindings. That should handle that. – JoxTraex Apr 09 '13 at 22:55
  • Thanks JoxTraex. I did have it working previously using a global flag, but I was trying to refactor using the thread messaging approach, as this is supposed to be 'superior' to global variables, that people seem to frown upon. Obviously, my problems in tying to do this are an argument in favor of globals to some extent. I think I might take your advice and revert to this approach. Cheers. – Andy Lee Apr 09 '13 at 23:02