Android - howto pass data to the Runnable in runOnUiThread? Android - howto pass data to the Runnable in runOnUiThread? multithreading multithreading

Android - howto pass data to the Runnable in runOnUiThread?


The problem you found is that

Inner classes in Java capture ("close over") the lexical scope in which they are defined. But they only capture variables that are declared "final".

If this is clear as mud, there's a good discussion of the details here:Cannot refer to a non-final variable inside an inner class defined in a different method

But your solution looks fine. In addition, provided that data is final, you could simplify the code to this:

public void OnNewSensorData(final Data data) {    runOnUiThread(new Runnable() {        public void run() {            // use data here            data.doSomething();        }    });}


If you want to avoid using an intermediate final variable (as described by Dan S), you can implement Runnable with an additional method to set Data:

public class MyRunnable implements Runnable {  private Data data;  public void setData(Data _data) {    this.data = _data;  }  public void run() {    // do whatever you want with data  }}

You can then call the method like this:

public void OnNewSensorData(Data data) {  MyRunnable runnable = new MyRunnable();  runnable.setData(data);  runOnUiThread(runnable);}

you could also make MyRunnable's constructor take in the Data instance as an argument:

public class MyRunnable implements Runnable {  private Data data;  public MyRunnable(Data _data) {    this.data = _data;  }  public void run() {    ...  }}

and then just say runOnUiThread(new MyRunnable(data));


I had a similar problem where I wanted to pass information into the thread. To solve it with the android system, I modifying corsiKa's answer in: Runnable with a parameter?

You can declare a class right in the method and pass the param as shown below:

void Foo(String str) {    class OneShotTask implements Runnable {        String str;        OneShotTask(String s) { str = s; }        public void run() {            someFunc(str);        }    }    runOnUiThread(new OneShotTask(str));}