# 翻译引擎(TranslationEngine)

通过实现 TranslationEngine 接口,可以为 MT 管理器的翻译模式和文本输入框增加翻译功能。

建议:推荐继承 BaseTranslationEngine 而非直接实现 TranslationEngine 接口,基类提供了常用的默认实现。

# 快速开始

public class TranslationEngineDemo extends BaseTranslationEngine {

    public TranslationEngineDemo() {
        super(new ConfigurationBuilder()
                // 关闭「跳过已翻译词条」
                .setForceNotToSkipTranslated(true)
                .build());
    }

    @NonNull
    @Override
    public String name() {
        return "{case_conversion}";
    }

    @NonNull
    @Override
    public List<String> loadSourceLanguages() {
        return List.of("src");
    }

    @NonNull
    @Override
    public List<String> loadTargetLanguages(String sourceLanguage) {
        return List.of("upper", "lower");
    }

    @NonNull
    @Override
    public String getLanguageDisplayName(String language) {
        return switch (language) {
            case "src" -> "原文";
            case "upper" -> "大写";
            case "lower" -> "小写";
            default -> "???";
        };
    }

    @NonNull
    @Override
    public String translate(String text, String sourceLanguage, String targetLanguage) {
        if (targetLanguage.equals("upper"))
            return text.toUpperCase(); // 转为大写
        else
            return text.toLowerCase(); // 转为小写
    }
}

# 接口概览

# TranslationEngine 接口

方法 说明
void init(PluginContext context) 初始化翻译引擎
PluginContext getContext() 获取插件上下文
String name() 获取翻译引擎名称
Configuration getConfiguration() 获取配置信息
List<String> loadSourceLanguages() 加载源语言列表
List<String> loadTargetLanguages(String sourceLanguage) 加载目标语言列表
String getLanguageDisplayName(String language) 将语言代码转换为显示名称
void beforeStart() 翻译开始前的回调(UI线程)
void onStart() 翻译开始时的回调(子线程)
String translate(String text, String sourceLanguage, String targetLanguage) 执行翻译(子线程)
void onFinish() 翻译结束时的回调(子线程)
void afterFinish() 翻译结束后的回调(UI线程)
boolean onError(Exception e) 错误处理回调(UI线程)

# BaseTranslationEngine 基类

BaseTranslationEngine 提供了 TranslationEngine 接口的基础实现:

  • 自动管理 PluginContext 的存储和获取
  • 提供简化的 init() 方法供子类重写
  • 默认启用格式化占位符自动修复功能
  • 提供基于 MT 内置语言库的 getLanguageDisplayName() 实现
  • 生命周期方法的空实现,子类可按需重写

# 生命周期

TranslationEngine 的生命周期如下:

  1. init(PluginContext) - 引擎初始化,每个实例仅调用一次
  2. beforeStart() - 翻译任务开始前的回调 [UI线程]
  3. onStart() - 翻译任务开始时的回调 [子线程]
  4. translate(String, String, String) - 执行翻译,根据任务需求可能调用一次或多次 [子线程]
  5. onFinish() - 翻译任务结束时的回调 [子线程]
  6. afterFinish() - 翻译任务结束后的回调 [UI线程]

注意:如果在 translate() 过程中发生错误,将调用 onError(),且不会再调用 onFinish()afterFinish()

# 详细说明

# init

void init(PluginContext context)

初始化翻译引擎。此方法在引擎实例创建后调用,且每个实例仅调用一次。

参数:

  • context - MT插件上下文,用于访问插件资源和MT功能

线程: UI线程

# getContext

PluginContext getContext()

获取插件上下文。

返回值: init() 中传入的上下文对象

# name

@NonNull
String name()

获取翻译引擎的显示名称。

返回值: 翻译引擎名称,将显示在翻译引擎选择列表中

本地化支持: 支持 {key} 格式的本地化文本引用,如 {my_engine} 会自动转换为对应的本地化文本。详见 本地化文本

# getConfiguration

@NonNull
Configuration getConfiguration()

获取翻译引擎的配置信息。

返回值: 配置对象,不能为 null

详见 配置选项 章节。

# loadSourceLanguages

@NonNull
List<String> loadSourceLanguages()

加载支持的源语言列表。返回的语言代码将用于 loadTargetLanguages()translate() 方法。

返回值: 源语言代码列表,如 ["auto", "en", "zh-CN", "ru"]

# loadTargetLanguages

@NonNull
List<String> loadTargetLanguages(String sourceLanguage)

加载支持的目标语言列表。

如果 Configuration.targetLanguageMutable 为 true,每当用户切换源语言时都会调用此方法来更新目标语言列表;为 false 时仅在界面初始化时调用一次,此时 sourceLanguage 参数没有实际意义。

参数:

  • sourceLanguage - 源语言代码,仅当 targetLanguageMutable 为 true 时有意义

返回值: 目标语言代码列表,如 ["en", "zh-CN", "ru"]

# getLanguageDisplayName

@NonNull
String getLanguageDisplayName(String language)

将语言代码转换为用户友好的显示名称。用于在界面上展示 loadSourceLanguages()loadTargetLanguages() 返回的语言代码。

参数:

  • language - 语言代码,如 "en"、"zh-CN"

返回值: 语言的显示名称,如 "English"、"简体中文"

使用 MT 内置语言名称:

可以使用 context.getString("lang:xx") 获取 MT 内置的语言名称

@NonNull
@Override
public String getLanguageDisplayName(String language) {
    String name = getContext().getStringNullable("lang:" + language);
    return name != null ? name : language;
}

BaseTranslationEngine 已提供此实现,直接继承即可。

# beforeStart

void beforeStart()

翻译开始前的回调。在 onStart() 之前调用,运行在 UI线程,禁止执行耗时操作或网络请求。

线程: UI线程

# onStart

void onStart()

翻译开始时的回调。在 beforeStart() 之后、translate() 之前调用,运行在 子线程,可执行耗时操作或网络请求。

线程: 子线程

# translate

@NonNull
String translate(String text, String sourceLanguage, String targetLanguage) throws IOException

执行文本翻译。此方法运行在 子线程,可能被 多次调用 以翻译不同的文本。

参数:

  • text - 待翻译的文本。在翻译模式功能中,如果 Configuration.acceptTranslated 为 false,则始终传入原始文本;为 true 时可能传入已翻译的文本
  • sourceLanguage - 源语言代码
  • targetLanguage - 目标语言代码

返回值: 翻译后的文本,不能为 null

异常: IOException - 翻译过程中发生的 IO 异常(如网络错误)

线程: 子线程

# onFinish

void onFinish()

翻译结束或用户取消后的回调。在 translate() 之后、afterFinish() 之前调用,运行在 子线程,可执行耗时操作和网络请求。

线程: 子线程

# afterFinish

void afterFinish()

翻译结束或用户取消后的回调。在 onFinish() 之后调用,运行在 UI线程,禁止执行耗时操作或网络请求。

线程: UI线程

# onError

boolean onError(Exception e)

翻译错误处理回调。当 translate() 过程中发生异常时调用,运行在 UI线程,可用于自定义错误提示。

注意:调用此方法后,onFinish()afterFinish() 将不会被调用。

参数:

  • e - 发生的异常

返回值:

  • true - 表示已自行处理错误,MT 不显示默认的错误对话框
  • false - 表示让 MT 显示默认错误提示

线程: UI线程

# 配置选项

翻译引擎的配置通过 Configuration 类管理。由于 Configuration 的字段都是 final 无法更改,需要通过 ConfigurationBuilder 创建:

Configuration config = new ConfigurationBuilder()
    .setAcceptTranslated(false)
    .setAutoRepairFormatSpecifiersError(true)
    .build();

# 配置项说明

配置项 默认值 说明
acceptTranslated false 是否接受已翻译的文本作为输入
forceNotToSkipTranslated false 是否强制不跳过已翻译词条
targetLanguageMutable false 目标语言列表是否随源语言变化
autoRepairFormatSpecifiersError false 是否自动修复格式化占位符翻译错误
disableAutoHideLanguage false 是否禁用语言自动隐藏功能

# setAcceptTranslated

ConfigurationBuilder setAcceptTranslated(boolean acceptTranslated)

在翻译模式功能中,设置是否接受已翻译过的文本作为输入。

例如词条 "Apple" 第一次翻译结果为 "苹果",再次翻译时:

  • false(默认)- 传入原始文本 "Apple"
  • true - 传入已翻译的文本 "苹果"

# setForceNotToSkipTranslated

ConfigurationBuilder setForceNotToSkipTranslated(boolean forceNotToSkipTranslated)

在翻译模式功能中,设置是否强制不跳过已翻译的词条。

启用后,翻译模式界面上的"跳过已翻译"选项将被隐藏,所有词条都会被翻译。

# setTargetLanguageMutable

ConfigurationBuilder setTargetLanguageMutable(boolean targetLanguageMutable)

设置目标语言列表是否随源语言变化。

某些翻译引擎的目标语言列表会根据所选源语言动态变化,此时应设为 true,MT 会在源语言改变时重新调用 loadTargetLanguages()

# setAutoRepairFormatSpecifiersError

ConfigurationBuilder setAutoRepairFormatSpecifiersError(boolean autoRepairFormatSpecifiersError)

设置是否自动修复格式化占位符的翻译错误。

某些翻译引擎可能会错误地翻译格式化占位符,如将 "%s" 翻译为 "%S"。启用此选项后,MT 会自动修复这类常见错误。

注意:BaseTranslationEngine 默认启用此选项。

# setDisableAutoHideLanguage

ConfigurationBuilder setDisableAutoHideLanguage(boolean disableAutoHideLanguage)

设置是否禁用语言自动隐藏功能。

对于支持大量语言的翻译引擎(如 Google 翻译),用户可以在翻译模式中隐藏不常用的语言。如果不希望引擎的语言被用户隐藏,可设为 true。

# 完整示例

# 基础翻译引擎

以下是一个简单的大小写转换翻译引擎:

public class TranslationEngineDemo extends BaseTranslationEngine {

    public TranslationEngineDemo() {
        super(new ConfigurationBuilder()
                .setForceNotToSkipTranslated(true)
                .build());
    }

    @NonNull
    @Override
    public String name() {
        return "{case_conversion}";
    }

    @NonNull
    @Override
    public List<String> loadSourceLanguages() {
        return List.of("src");
    }

    @NonNull
    @Override
    public List<String> loadTargetLanguages(String sourceLanguage) {
        return List.of("upper", "lower");
    }

    @NonNull
    @Override
    public String getLanguageDisplayName(String language) {
        return switch (language) {
            case "src" -> "原文";
            case "upper" -> "大写";
            case "lower" -> "小写";
            default -> "???";
        };
    }

    @NonNull
    @Override
    public String translate(String text, String sourceLanguage, String targetLanguage) {
        if (targetLanguage.equals("upper"))
            return text.toUpperCase();
        else
            return text.toLowerCase();
    }
}

# 在线翻译引擎

以下示例展示如何实现一个在线翻译引擎:

public class OnlineTranslationEngine extends BaseTranslationEngine {

    private OkHttpClient httpClient = new OkHttpClient.Builder().build();

    @NonNull
    @Override
    public String name() {
        return "在线翻译";
    }

    @NonNull
    @Override
    public List<String> loadSourceLanguages() {
        return List.of("auto", "en", "zh-CN", "ja", "ko");
    }

    @NonNull
    @Override
    public List<String> loadTargetLanguages(String sourceLanguage) {
        return List.of("en", "zh-CN", "ja", "ko");
    }

    @NonNull
    @Override
    public String translate(String text, String sourceLanguage, String targetLanguage) throws IOException {
        // 调用在线翻译 API
        Request request = new Request.Builder()
                .url("https://api.example.com/translate?text=" + text
                    + "&from=" + sourceLanguage
                    + "&to=" + targetLanguage)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("翻译请求失败: " + response.code());
            }

            String result = response.body().string();
            // 解析 JSON 结果
            return parseTranslationResult(result);
        }
    }

    @Override
    public boolean onError(Exception e) {
        // 自定义错误提示
        if (e instanceof IOException) {
            getContext().showToastL("网络错误:" + e.getMessage());
            return true; // 不显示默认错误对话框
        }
        return false; // 显示默认错误对话框
    }

    private String parseTranslationResult(String json) {
        // 解析 JSON 结果的逻辑
        return json;
    }
}

# 接口配置

所有实现的翻译引擎接口都必须在模块的 build.gradle 中注册:

mtPlugin {
    pluginID = "com.example.myplugin"
    versionCode = 1
    versionName = "v1.0"
    name = "翻译插件"

    interfaces = [
        "com.example.myplugin.TranslationEngineDemo",
        "com.example.myplugin.OnlineTranslationEngine",
    ]
}

# 相关接口