英文:
Updating UI from Runnable with parameters
问题
我在Stackoverflow上找到了多种方法来做这件事,但仍然没有找到一个使用参数的好方法。在我的情况下,我有一个线程,需要不断地使用日志信息更新UI主线程(我没有使用Asynctask;我正在实现Google Maps的TileProvider接口)。
以下是我在线程中运行的代码,它能够正常工作:
Handler mainHandler = new Handler(Looper.getMainLooper());
...
public void debugMsg(final String msg)
{
Runnable myRunnable = (new Runnable()
{
@Override
public void run()
{
Log.Add(msg); // 在主线程中更新UI的静态函数
}
});
mainHandler.post(myRunnable);
}
问题是,如果我理解正确,每次调用debugMsg时,它都会实例化一个新的Runnable对象。我认为这不是一个很好的做法,特别是因为它会频繁地进行,所以我想知道是否有一种方法可以在我的线程内重用该runnable。或者也许有更好的做法...
英文:
I found multiple options to do that on Stackoverflow, but still haven't found a good way to do it with parameters. In my case, I have a thread that continuously needs to update the UI main thread with logging information (I'm not using Asynctask; I'm implementing TileProvider interface from Google Maps)
This is what I have that runs in my thread and it works:
Handler mainHandler = new Handler(Looper.getMainLooper());
...
public void debugMsg(final String msg)
{
Runnable myRunnable = (new Runnable()
{
@Override
public void run()
{
Log.Add(msg); // static function that update the UI in the main thread
}
});
mainHandler.post(myRunnable);
}
Problem is that if I understand correctly, every time I call debugMsg, it is going to instantiate a new Runnable object. I don't think that's a very good practice especially because it's going to be heavily done, so I would like to know if there is way to reuse that runnable inside my thread. Or maybe there's a better way of doing it...
答案1
得分: 1
如果您想要重用Runnable
,可以将其简单地存储为成员变量。
private Runnable myRunnable = new Runnable() {
@Override
public void run() { ... };
};
您可能会想,在需要参数的情况下,可以使用Consumer
。
private Consumer<String> myConsumer = (str) -> { Log.d("tag", str); };
然后在debugMsg
中:
mainHandler.post(() -> { myConsumer.accept(msg); });
然而,您的Lambda表达式仍然会成为每次运行debugMsg
时实例化的函数式接口对象。但主要逻辑不会被重新创建,myConsumer
将被重用。
更新:
您可以自己实现Runnable
接口,类似于以下内容:
public abstract class ParameterisedRunnable implements Runnable {
public String param = "";
public void setParam(String str) {
param = str;
}
}
然后像普通的Runnable
一样创建ParameterisedRunnable
的实例(重写run
方法)。
private ParameterisedRunnable myRunnable = new ParameterisedRunnable() {
@Override
public void run() {
Log.d("tag", param);
}
};
您可以像这样使用它:
myRunnable.setParam(msg);
mainHandler.post(myRunnable);
英文:
If you want to reuse the Runnable
, you can easily store it as a member variable.
private Runnable myRunnable = new Runnable() {
@Override
public void run() { ... };
}
You might think, in case of having parameter, you can use consumer.
private Consumer<String> myConsumer = (str) - > { Log.d("tag", str); };
And then in debugMsg
mainHandler.post(() -> { myConsumer.accept(msg); });
However, your lambda still will be an object of functional interface instantiated every time you run debugMsg
. But the main logic will not be recreated and myConsumer
will be reused.
UPD:
You can implement Runnable interface yourself, something like
public abstract class ParameterisedRunnable implements Runnable {
public String param = "";
public void setParam(String str) {
param = str;
}
}
And then just create the instance of ParameterisedRunnable like the regular Runnable (overriding run method).
private ParameterisedRunnable myRunnable = new ParameterisedRunnable() {
@Override
public void run() {
Log.d("tag", param);
}
}
You will able to use it like that.
myRunnable.setParam(msg);
mainHandler.post(myRunnable);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论