Android中每个X Millis执行代码的方式如下:
void test(Handler handler) {
handler.post(new Runnable() {
@Override
public void run() {
// Do something
// Do it every 200ms
handler.postDelayed(this, 200);
}
});
}
但是,我已经开始更改代码以尽可能使用lambda。将此模式更改为lambda有一个问题:lambda内部的this
引用了外部类,因此不能在postDelayed(...)
中使用。
要使其工作,我必须保留对lambda的引用。但是,该引用不能在局部变量中。这意味着为此lambda可运行的对象找到一个有意义的名称,并将其存储为类成员:
private Runnable intervalRunnable;
...
void testWithLambda() {
this.intervalRunnable = () -> {
// Do something
// Do it every 200ms
handler.postDelayed(intervalRunnable, 200);
};
handler.post(intervalRunnable);
}
因此,代码更加“现代”,但丑陋且难以维护。
还有另一种解决此问题的方法吗?我喜欢lambda,但我不想在班级上使用这些引用。在这些选项之间,我更喜欢使用匿名类模式。
答案 0 :(得分:1)
15.27.2。 Lambda Body ... 实际上,lambda表达式需要谈论自己(或者自称 递归或调用其其他方法)...如果需要 lambda表达式引用自己(就像通过它),一个方法 引用或匿名内部类代替。
我基本上是说“如果您需要递归lambda,请不要使用lambda。”
基于此,似乎我们在第二个示例中遇到了麻烦,在该示例中,您省去了对类的lambda引用(尽管可以说或多或少地等同于使用方法引用)。
您可以尝试隐藏使用方法引用的事实:
Handler handler = new Handler();
Runnable everyXMillis(Runnable inner, int ms) {
return () -> {
inner.run();
handler.postDelayed(everyXMillis(inner, ms), ms);
};
}
void testWithMethodReference() {
handler.post(everyXMillis(() -> {
// do something
}, 200));
}
...但是...太糟糕了!如果您担心拥有丑陋且难以维护的代码,似乎最好使用更冗长的匿名Runnable。