有谁知道如何解决以下问题。我想从回调中返回一个String,但我只得到“最终的局部变量s不能被分配,因为它是在一个封闭的类型中定义的”,因为final。
public String getConstraint(int indexFdg) {
final String s;
AsyncCallback<String> callback = new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
public void onSuccess(String result) {
s = result;
}
};
SpeicherService.Util.getInstance().getConstraint(indexFdg, callback);
return s;
}
答案 0 :(得分:15)
异步回调的重点是在将来的某个时间通知您异步发生的事情。如果在方法运行完毕后将设置<{1}},则无法从s
返回getConstraint
。
在处理异步回调时,您必须重新考虑程序的流程。而不是getConstraint
返回值,而应该通过回调调用使用该值的代码。
作为一个简单(不完整)的例子,你需要改变这个:
String s = getConstraint();
someGuiLabel.setText(s);
这样的事情:
myCallback = new AsyncCallback<String>() {
public void onSuccess(String result) {
someGuiLabel.setText(result);
}
}
fetchConstraintAsynchronously(myCallback);
一种流行的替代方案是 future 的概念。未来是一个对象,您可以立即返回,但在将来的某个时刻只会有一个值。它是一个容器,您只需要在要求它时等待值。
您可以考虑为持有干洗衣服的机票持有未来。你立刻得到了票,可以把它放在你的钱包里,交给朋友......但是一旦你需要换一件真正的套装,你需要等到套装准备就绪。
Java有这样一个类(Future<V>
),ExecutorService API广泛使用。
答案 1 :(得分:3)
另一种解决方法是定义一个名为SyncResult
public class SyncResult {
private static final long TIMEOUT = 20000L;
private String result;
public String getResult() {
long startTimeMillis = System.currentTimeMillis();
while (result == null && System.currentTimeMillis() - startTimeMillis < TIMEOUT) {
synchronized (this) {
try {
wait(TIMEOUT);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return result;
}
public void setResult(String result) {
this.result = result;
synchronized (this) {
notify();
}
}
}
然后将您的代码更改为此
public String getConstraint(int indexFdg) {
final SyncResult syncResult = new SyncResult();
AsyncCallback<String> callback = new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
public void onSuccess(String result) {
syncResult.setResult(result);
}
};
SpeicherService.Util.getInstance().getConstraint(indexFdg, callback);
return syncResult.getResult();
}
在调用getResult()
方法或达到setResult(String)
之前,TIMEOUT
方法将被屏蔽。