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

  • Android:新线程Runnable在主线程中执行
  • 多进程内容提供者同步到默认的一个
  • Android垃圾收集器的技术细节
  • 应用程序挂起并挂起所有线程,同时使用AsyncTask
  • WebViewCore内部线程中的StatFs中的IllegalArgumentException
  • IntentService类没有在主ui线程上运行AsyncTask。 必须从主线程调用方法execute,当前推断的线程是worker
  • 如何使用runOnUiThread而不会收到“无法对非静态方法进行静态引用”的编译器错误
  • Android主线程阻塞WebView线程
  • 你发现的问题是

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