作为大学项目的一部分,我正在开发一个简单的翻译应用程序。对于翻译过程,我使用Retrofit查询MyMemory's Translate API,并将翻译后的输出作为字符串检索。这在大多数情况下都可以正常工作,但在程序的其他方面却引起了一些问题。

当我打电话从库中检索翻译时,随后的方法在完全接收到翻译之前就开始运行-这会阻止这些方法完全起作用,因为它们依赖于所接收的翻译。

以下是我的代码的一些相关代码片段,它们可能会更好地解释该问题:

TranslateAPI :(我用来检索翻译的接口)

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)方法成功地将转换后的输出作为字符串返回。

现在,为了确切说明出了什么问题,请针对我的主要活动假设以下代码片段:

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

}


此处发生的是runChatbot()中的print语句在调用翻译API之前执行。这不是期望的行为,因为我希望translateOutput()方法在以下任何指令之前完全执行。

任何帮助深表感谢。提前致谢 :)

更新:初始答案后的当前代码

TranslateAPI-声明

public interface Callbacks {
    void onTranslationReceived(String result);
    void onTranslationFailed();
}


TranslateAPI-translate()

    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
}


然后,一旦您在回调中收到响应,就可以执行翻译结果。这样,您知道在转换完成之前,您永远不会对转换结果执行任何操作。

编辑以回应评论



因此,为了在收到翻译响应后将响应实际发送到您的活动,您需要将对您的活动的引用传递到TranslateAPI中。由于您的活动implements是回调,因此您只需在this中传递TranslateAPI translateApi = new TranslateAPI(this);

然后,在您的TranslateAPI中,需要使用此引用并将其用作回调的“侦听器”。因此,在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;
}


然后在onResponse()TranslateAPI回调中,您只需将值传递给侦听器,该侦听器会将其传递回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 - 在上一个方法完成之前调用的方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35612580/

10-09 09:22