Android – 如何将数据传递给runnable在runOnUiThread?

我需要更新一些用户界面,并使用runOnUiThread在UI线程内部runOnUiThread
现在,UI的数据来自另一个线程,在这里用data表示。

如何将数据传递给Runnable,那么它们可以用来更新UI? Android似乎不允许直接使用数据。 有没有一个优雅的方式来做到这一点?

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

我的解决scheme是在可运行的内部创build一个private Data sensordata ,并为其分配数据。 如果原始Data data是最终的,这只适用。

 public void OnNewSensorData(final Data data) { runOnUiThread(new Runnable() { private Data sensordata = data; public void run() { //use sensordata which is equal to data } }); } 

Solutions Collecting From Web of "Android – 如何将数据传递给runnable在runOnUiThread?"

你发现的问题是

Java中的内部类捕获(“接近”)定义它们的词法范围。 但是他们只捕获被声明为“最终”的variables。

如果这是清楚的泥巴,这里有一个很好的讨论的细节: 不能引用一个非最终variables内定义在一个不同的方法内部类

但你的解决scheme看起来不错 另外,假设data是最终的,你可以简化代码到这个:

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

如果要避免使用中间最终variables(如Dan S所述),则可以使用其他方法来实现Runnable以设置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 } } 

然后你可以调用这个方法:

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

你也可以使MyRunnable的构造函数作为一个参数在Data实例中:

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

然后就说runOnUiThread(new MyRunnable(data));

我有一个类似的问题,我想传递信息到线程中。 为了解决它与android系统,我修改corsiKa的答案:运行一个参数?

您可以在方法中声明一个类并传递参数,如下所示:

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

每当您的程序显示新Data ,您都需要进行更新。 你的第二个代码清单是完成这个的标准方法。 如果您继续更新线程中的Data ,可能会有一些捕获。 如果是这种情况,请考虑阻塞线程,直到UI完成更新或将数据复制到另一个Data对象。

内部发生的事情是,当匿名类运行时,JVM将引用复制到Data对象。 存储在里面的Data仍然可以改变。 如果你的方法需要额外的Data修改,只需使用另一个variables(对象引用),如: final Data finalData = data; 。 您也可以删除private Data sensordata = data; 并直接在你的运行方法中使用数据。

它可能看起来并不高雅,但这是Java将对象variables传递给匿名类的方式。 Java语言版本7中有更新的语法,但Android与Java语言版本5和6兼容。

这是一个典型的情况,其中调用服务callback来更新UI状态string(TextView textStatus)。 该服务可能是线程的。

该示例结合检查是否需要线程redirect以及实际的redirect:

  // service callbacks public void service_StatusTextChanged(final String s) { if( isOnUiThread() ) { textStatus.setText(s); } else { runOnUiThread(new Runnable() { @Override public void run() { textStatus.setText(s); } }); } } static public boolean isOnUiThread() { return Thread.currentThread() == Looper.getMainLooper().getThread(); } 

另请参见如何检查是否在Android的UI线程上运行?

 public static Activity globalContext = null; CommonSetting.globalContext = this;// put this in MainACtivity.onCreate() public void createToastShort(final String message) { runOnUiThread(new Runnable() { public void run() { Toast.makeText(CommonSetting.globalContext, message, Toast.LENGTH_SHORT).show(); } }); }