Android - 如何在runOnUiThread中将数据传递给Runnable?

Ski*_*kip 26 user-interface multithreading android arguments

我需要更新一些UI并使用UI线程在UI线程内完成.runOnUiThread
现在UI的数据来自另一个Thread,由data此处表示.

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

public void OnNewSensorData(Data data) {

    runOnUiThread(new Runnable() {
        public void run() {
            //use data
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

我的解决方案是private Data sensordata在runnable中创建一个fioeld ,并为其分配数据.如果原件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
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

spa*_*nia 37

你发现的问题是

Java中的内部类捕获("关闭")定义它们的词法范围.但它们只捕获声明为"最终"的变量.

如果这很清楚,那么这里有一个很好的讨论细节: 不能引用在不同方法中定义的内部类中的非final变量

但你的解决方案看起来不错 此外,如果data是最终的,您可以将代码简化为:

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


ale*_*ull 21

如果要避免使用中间最终变量(如Dan S所述),可以使用其他方法实现Runnable来设置数据:

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
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以像这样调用方法:

public void OnNewSensorData(Data data) {
  MyRunnable runnable = new MyRunnable();
  runnable.setData(data);
  runOnUiThread(runnable);
}
Run Code Online (Sandbox Code Playgroud)

你也可以让MyRunnable的构造函数接受Data实例作为参数:

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

  public void run() {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

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


Jam*_*vec 6

我有一个类似的问题,我想将信息传递给线程.要用android系统解决它,我修改了corsiKa的答案:Runnable带参数?

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

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