在上一个方法完成之前调用的方法
Method Called Before Previous Method Finishes
作为大学项目的一部分,我正在开发一个简单的翻译应用程序。对于翻译过程,我使用 Retrofit 查询 MyMemory's Translate API 并将翻译后的输出检索为字符串。这在大多数情况下工作正常,但它在我的程序的其他区域引起了一些问题。
当我调用从库中检索翻译时,后续方法在完全收到翻译之前开始 运行 - 这会阻止这些方法完全工作,因为它们依赖于收到的翻译。
以下是我的代码的一些相关片段,可以更好地解释问题:
翻译API:(我用来检索翻译的界面)
public class TranslateAPI {
private static final String ENDPOINT = "http://api.mymemory.translated.net";
public final static String FRENCH = "FR";
public final static String ENGLISH = "EN";
public final static String ITALIAN = "IT";
public final static String GREEK = "EL";
public final static String SPANISH = "ES";
private final TranslateService mService;
String translation = "";
public interface TranslateService {
@GET("/get")
Call<TranslatedData> getTranslation(
@Query("q") String textToTranslate,
@Query(value = "langpair", encoded = true)
String languagePair);
}
public TranslateAPI() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
mService = retrofit.create(TranslateService.class);
}
public String translate(final String textToTranslate, final String fromLanguage, final String toLanguage) {
mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
.enqueue(new Callback<TranslatedData>() {
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output =
String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate,
fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
}
@Override
public void onFailure(Throwable t) {
System.out.println("[DEBUG]" + " RestApi onFailure - " + "");
}
});
return translation;
}
}
在上面的代码中,translate(final String textToTranslate, final String fromLanguage, final String toLanguage) 方法成功returns 将翻译输出作为字符串。
现在,为了准确说明问题出在哪里,假设我的主要代码片段如下 activity:
private void runChatBot() {
translateOutput(input, targetLanguage); //calls the translate method of the TranslateAPI class
System.out.println("translatedOutput value in MainActivity: " + translatedOutput);
//Use translated output here
}
这里发生的是 运行Chatbot() 中的打印语句在调用翻译 API 之前执行。这不是所需的行为,因为我希望 translateOutput() 方法在任何后续指令之前完全执行。
非常感谢任何帮助。提前致谢:)
更新:初始答案后的当前代码
翻译API - 声明
public interface Callbacks {
void onTranslationReceived(String result);
void onTranslationFailed();
}
翻译API - 翻译()
public void translate(final String textToTranslate, final String fromLanguage, final String toLanguage) {
mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
.enqueue(new Callback<TranslatedData>() {
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output =
String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate,
fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
}
@Override
public void onFailure(Throwable t) {
System.out.println("[DEBUG]" + " RestApi onFailure - " + "");
}
});
}
主要活动:
@Override
public void onTranslationReceived(String result) {
runChatBot();
}
@Override
public void onTranslationFailed() {
//Handle failure here
}
public void runChatBot() {
translatedOutput = translateAPI.getTranslation();
System.out.println("translatedOutput value in MainActivity: " + translatedOutput);
userOutputView.setText(translatedOutput);
ttsResponse(translatedOutput, TTSLanguage);
setVisualCue(chatBot.getVisualMatch());
chatBot.clearResults();
}
由于您的 translate()
方法是异步的,您应该在 TranslateAPI
中定义一个回调,以便在收到结果时将结果发送回您的 Activity。通过这样做,您将只在知道收到来自 TranslateAPI
.
的回复后才对翻译结果执行工作
所以在TranslateAPI
你会定义一个回调接口:
public interface Callbacks {
void onTranslationReceived(String result);
}
然后你会让你的 Activity 实现 TranslateAPI.Callbacks
并像这样实现回调:
public void onTranslationReceived(String result) {
//do something with the result
runChatBot(result); //or something similar
}
然后,一旦您在回调中收到响应,就可以对翻译结果进行任何操作。这样,您就知道在翻译完成之前您永远不会对翻译结果执行任何操作。
根据评论进行编辑
因此,为了在收到翻译响应后实际将响应发送到您的 Activity,您需要将对 Activity 的引用传递到 TranslateAPI
。由于您的 Activity implements
回调,您只需将 this
传递给:TranslateAPI translateApi = new TranslateAPI(this);
然后在您的 TranslateAPI
中,您需要获取此参考并将其用作回调的 "listener"。因此,在 TranslateAPI
中,您需要定义一个像这样的变量 private Callbacks listener;
,并且您将在 TranslateAPI
构造函数中为它分配从 Activity 传入的值。因此,您的 TranslateAPI
构造函数可能如下所示:
public TranslateAPI(Callbacks listener) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
mService = retrofit.create(TranslateService.class);
//this is the line you would add...
this.listener = listener;
}
然后在 TranslateAPI
中的 onResponse()
回调中,您只需将值传递给侦听器,侦听器将其传递回 Activity 中实现的方法。像这样:
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output = String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate, fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
//this is the line you would add...
listener.onTranslateReceived(translation);
}
希望这有助于澄清事情。如果您还有其他问题,请告诉我!
尝试使用处理程序在翻译完成时进行通知,然后执行所需的操作。谢谢
发生这种情况是因为代码是异步执行的。您的改造网络请求需要一些时间才能完成,因此默认情况下,java 将在结束之前执行下一行代码。要解决此问题,您必须使用改装回调 onResponse 和 onFailure。
我建议您创建一个新接口并将其传递给 TranslateApiCode 的构造函数 os 方法。类似于:
public interface OnTranslate {
void onSuccess(); // here you can pass any object you need later
void onError(); // here you can pass any object you need later
}
public String translate(final String textToTranslate, final String fromLanguage, final String toLanguage) {
mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
.enqueue(new Callback<TranslatedData>() {
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output =
String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate,
fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
myOnTranslateVariable.onSuccess();
}
@Override
public void onFailure(Throwable t) {
System.out.println("[DEBUG]" + " RestApi onFailure - " + "");
myOnTranslateVariable.onError();
}
});
return translation;
}
private void runChatBot() {
translateOutput(input, targetLanguage, new OnTranslate() {
void onSucess() {
System.out.println("translatedOutput value in MainActivity: " + translatedOutput);
}
void onError() {
System.out.println("some error happened");
}
}); //calls the translate method of the TranslateAPI class
//Use translated output here
}
作为大学项目的一部分,我正在开发一个简单的翻译应用程序。对于翻译过程,我使用 Retrofit 查询 MyMemory's Translate API 并将翻译后的输出检索为字符串。这在大多数情况下工作正常,但它在我的程序的其他区域引起了一些问题。
当我调用从库中检索翻译时,后续方法在完全收到翻译之前开始 运行 - 这会阻止这些方法完全工作,因为它们依赖于收到的翻译。
以下是我的代码的一些相关片段,可以更好地解释问题:
翻译API:(我用来检索翻译的界面)
public class TranslateAPI {
private static final String ENDPOINT = "http://api.mymemory.translated.net";
public final static String FRENCH = "FR";
public final static String ENGLISH = "EN";
public final static String ITALIAN = "IT";
public final static String GREEK = "EL";
public final static String SPANISH = "ES";
private final TranslateService mService;
String translation = "";
public interface TranslateService {
@GET("/get")
Call<TranslatedData> getTranslation(
@Query("q") String textToTranslate,
@Query(value = "langpair", encoded = true)
String languagePair);
}
public TranslateAPI() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
mService = retrofit.create(TranslateService.class);
}
public String translate(final String textToTranslate, final String fromLanguage, final String toLanguage) {
mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
.enqueue(new Callback<TranslatedData>() {
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output =
String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate,
fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
}
@Override
public void onFailure(Throwable t) {
System.out.println("[DEBUG]" + " RestApi onFailure - " + "");
}
});
return translation;
}
}
在上面的代码中,translate(final String textToTranslate, final String fromLanguage, final String toLanguage) 方法成功returns 将翻译输出作为字符串。
现在,为了准确说明问题出在哪里,假设我的主要代码片段如下 activity:
private void runChatBot() {
translateOutput(input, targetLanguage); //calls the translate method of the TranslateAPI class
System.out.println("translatedOutput value in MainActivity: " + translatedOutput);
//Use translated output here
}
这里发生的是 运行Chatbot() 中的打印语句在调用翻译 API 之前执行。这不是所需的行为,因为我希望 translateOutput() 方法在任何后续指令之前完全执行。
非常感谢任何帮助。提前致谢:)
更新:初始答案后的当前代码
翻译API - 声明
public interface Callbacks {
void onTranslationReceived(String result);
void onTranslationFailed();
}
翻译API - 翻译()
public void translate(final String textToTranslate, final String fromLanguage, final String toLanguage) {
mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
.enqueue(new Callback<TranslatedData>() {
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output =
String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate,
fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
}
@Override
public void onFailure(Throwable t) {
System.out.println("[DEBUG]" + " RestApi onFailure - " + "");
}
});
}
主要活动:
@Override
public void onTranslationReceived(String result) {
runChatBot();
}
@Override
public void onTranslationFailed() {
//Handle failure here
}
public void runChatBot() {
translatedOutput = translateAPI.getTranslation();
System.out.println("translatedOutput value in MainActivity: " + translatedOutput);
userOutputView.setText(translatedOutput);
ttsResponse(translatedOutput, TTSLanguage);
setVisualCue(chatBot.getVisualMatch());
chatBot.clearResults();
}
由于您的 translate()
方法是异步的,您应该在 TranslateAPI
中定义一个回调,以便在收到结果时将结果发送回您的 Activity。通过这样做,您将只在知道收到来自 TranslateAPI
.
所以在TranslateAPI
你会定义一个回调接口:
public interface Callbacks {
void onTranslationReceived(String result);
}
然后你会让你的 Activity 实现 TranslateAPI.Callbacks
并像这样实现回调:
public void onTranslationReceived(String result) {
//do something with the result
runChatBot(result); //or something similar
}
然后,一旦您在回调中收到响应,就可以对翻译结果进行任何操作。这样,您就知道在翻译完成之前您永远不会对翻译结果执行任何操作。
根据评论进行编辑
因此,为了在收到翻译响应后实际将响应发送到您的 Activity,您需要将对 Activity 的引用传递到 TranslateAPI
。由于您的 Activity implements
回调,您只需将 this
传递给:TranslateAPI translateApi = new TranslateAPI(this);
然后在您的 TranslateAPI
中,您需要获取此参考并将其用作回调的 "listener"。因此,在 TranslateAPI
中,您需要定义一个像这样的变量 private Callbacks listener;
,并且您将在 TranslateAPI
构造函数中为它分配从 Activity 传入的值。因此,您的 TranslateAPI
构造函数可能如下所示:
public TranslateAPI(Callbacks listener) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ENDPOINT)
.addConverterFactory(GsonConverterFactory.create())
.build();
mService = retrofit.create(TranslateService.class);
//this is the line you would add...
this.listener = listener;
}
然后在 TranslateAPI
中的 onResponse()
回调中,您只需将值传递给侦听器,侦听器将其传递回 Activity 中实现的方法。像这样:
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output = String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate, fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
//this is the line you would add...
listener.onTranslateReceived(translation);
}
希望这有助于澄清事情。如果您还有其他问题,请告诉我!
尝试使用处理程序在翻译完成时进行通知,然后执行所需的操作。谢谢
发生这种情况是因为代码是异步执行的。您的改造网络请求需要一些时间才能完成,因此默认情况下,java 将在结束之前执行下一行代码。要解决此问题,您必须使用改装回调 onResponse 和 onFailure。
我建议您创建一个新接口并将其传递给 TranslateApiCode 的构造函数 os 方法。类似于:
public interface OnTranslate {
void onSuccess(); // here you can pass any object you need later
void onError(); // here you can pass any object you need later
}
public String translate(final String textToTranslate, final String fromLanguage, final String toLanguage) {
mService.getTranslation(textToTranslate, URLEncoder.encode(fromLanguage + "|" + toLanguage))
.enqueue(new Callback<TranslatedData>() {
@Override
public void onResponse(Response<TranslatedData> response, Retrofit retrofit) {
String output =
String.format(response.body().responseData.translatedText);
String.format("Translation of: %s, %s->%s = %s", textToTranslate,
fromLanguage, toLanguage, response.body().responseData.translatedText);
System.out.println("Result: " + output);
translation = output;
System.out.println("The result of the field translation is: " + translation);
myOnTranslateVariable.onSuccess();
}
@Override
public void onFailure(Throwable t) {
System.out.println("[DEBUG]" + " RestApi onFailure - " + "");
myOnTranslateVariable.onError();
}
});
return translation;
}
private void runChatBot() {
translateOutput(input, targetLanguage, new OnTranslate() {
void onSucess() {
System.out.println("translatedOutput value in MainActivity: " + translatedOutput);
}
void onError() {
System.out.println("some error happened");
}
}); //calls the translate method of the TranslateAPI class
//Use translated output here
}