2

I need my app to start a thread (after clicking on a button) that does something, get me some variables then push a screen that displays those variables. The problem is that I can't get my screen to wait for that thread. Every time I run the app, I have to refresh the new screen to see the variables values. How should I deal with that? I used the invokeLater() method but that doesn't seem to work!

Here is my first screen's code:

import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.ButtonField;

public  class MyScreen extends MainScreen implements FieldChangeListener
{

    public MyScreen()
    {      
         super();

         setTitle("MyScreen!");
         ButtonField bf = new ButtonField("Start thread", ButtonField.CONSUME_CLICK) ;
         this.add(bf);

         bf.setChangeListener(this); 
    }

    public void fieldChanged(Field Field, int context) {

       MyThreadClass myThread = new MyThreadClass();
       myThread.start();

       UiApplication.getUiApplication().invokeLater(new Runnable() {
           public void run() {
              UiApplication.getUiApplication().pushScreen(new NewScreen());
          }
       });
    }
}

Where did I go wrong?

Nate
  • 31,017
  • 13
  • 83
  • 207
vanvana
  • 128
  • 7
  • 4
    inside the thread, when you get the values , then push the screen. – Rince Thomas May 16 '13 at 12:05
  • Sorry, what should I do inside the thread? – vanvana May 16 '13 at 12:07
  • inside the thread - after getting the variable, you can call the push screen. – Rince Thomas May 16 '13 at 12:10
  • or write a function to push the screen. When you get the variables, call that function. – Rince Thomas May 16 '13 at 12:11
  • Of course, calling it INSIDE the thread! How didn't I think of that. -_- Thank you, that worked just fine!! :) – vanvana May 16 '13 at 12:16
  • Try `java.lang.Thread.join()`, check this link http://www.tutorialspoint.com/java/lang/thread_join.htm – Rupak May 16 '13 at 15:57
  • @Rupak, that's really an overly complicated way to solve this problem. Simply do what Signare suggested (although see my comment on his answer for the complete solution). – Nate May 16 '13 at 21:18
  • 2
    @Nate, I will prefer the solution which will allow me separation of the screen pushing code and other code (the Thread, other business logic, etc.). If using `Thread.join()` complicates the solution then I think registering an interface to MyThreadClass in @Signare's solution will generalize the solution. Thankyou. – Rupak May 17 '13 at 08:42
  • @Rupak , I tried the `Thread.join()` method. That works too. And is not as complicated as @Nate says. I think that it's better than pushing my screen from inside the thread. – vanvana May 17 '13 at 22:28

1 Answers1

2

try this -

MyThreadClass myThread = new MyThreadClass();
myThread.start();

and

class MyThreadClass implements Runnable {
      public void run() {
          // here - your code for getting variables.

          // After getting your variable , push the screen.
          UiApplication.getUiApplication().invokeLater(new Runnable() {
              public void run() {
                  UiApplication.getUiApplication().pushScreen(new NewScreen());
              }
          });
      }
}
Nate
  • 31,017
  • 13
  • 83
  • 207
Rince Thomas
  • 4,158
  • 5
  • 25
  • 44
  • 1
    Actually, this only *half* solves the problem. Calling `pushScreen()` from the background thread won't work. You can't directly modify the UI from the background, so this will throw an `IllegalStateException`. Just wrap the call to `pushScren()` inside your `run()` method with a call to `UiApplication.getUiApplication().invokeLater()`. – Nate May 16 '13 at 21:16