mirror of
https://github.com/qingjian-team/qingjian.git
synced 2026-11-06 08:13:51 +00:00
青简 Android
Kotlin 的 InputMethodService 壳 + Rust 的 libqingjian_android.so。Android 的输入法跑在自己的进程里,
没有 Server / 薄壳之分,Engine 直接装在 .so 里,经 JNI 调用。
功能怎么用见 docs/user/platforms/android.md,各功能怎么接到 Core、取舍与踩坑见 docs/notes/android.md。
目录
core/:Rust crateqingjian-android(workspace 成员)。assembly装配 Engine;session/是Session,把软键盘操作翻成 Engine 调用 (keys打字选词与补全、scheme切方案与语言、options键盘设置、学习语言与私密输入、dictionaries附加词库重挂、display候选条上看得见的候选、cloud快捷翻译与释义兜底、prediction云联想与整句补全、clipboard拆词与常用语重挂、voice语音结果上屏、按设置换识别方与录音进出、swipe滑行解出的字母进组句);frame/是回给壳的一帧(JSON,另有语音识别的事VoiceEvent);store/是不经会话的数据读写(catalog符号 / 表情面板目录、clipboard/phrases剪贴板与常用语、code代码显示、dictionaries词库页的列出导入删除、learning高级页导出与清空的文件清单、shuangpin方案与键印、stats/vocabularyApp 的统计与生词本);cloud/是云端配置与测试连接;appearance/是外观(内置主题列表、按主题推出的键盘配色、设置页的主题预览、字号档);strip/把帧里的候选画成候选条位图(StripPainter),Handle是句柄背后的会话 + 画笔;jni/是出口(mod.rs句柄生命周期,operations.rs各个操作,strip.rs候选条位图:renderStrip画、copyStrip拷像素,theme.rs主题列表、键盘配色、预览与候选条换主题,voice.rs语音与识别配置、测试连接,swipe.rs滑行)。app/:Android 应用模块,包名app.qingjian.inputmethod,按职责分包,同一职能的再分子包:core/:JNI 封装(Native/Engine,「青简翻译」用的轻量句柄TranslationEngine)与首次启动解随包数据(BundledData);frame/帧的数据类,strip/画好的一帧候选条(位图 + 分界 + 可点区域),store/不要句柄的数据(面板目录、剪贴板与常用语、双拼方案、主题与预览图、统计、生词本)。service/:QingjianInputMethodService只管生命周期、设置与视图,InputPanel拼出整块视图;input/是输入逻辑:Composer(键 → Engine 操作 → 输入框)、Language输入语言、EditorKind哪些输入框不过引擎、EnterLabel回车键文字。keyboard/:自绘键盘。KeyboardView管触摸,SideColumn九宫格拼音列,BottomActionsView全面屏底部操作条,Haptics震动,SwipeTrail一笔滑行的判定、轨迹与交 Rust 的 JSON;layout/键位与排版(Key、KeyboardLayout键位表、KeyboardMetrics),paint/绘制(KeyPainter、KeyIcons)。theme/:配色。Palette键盘与面板(由 Rust 按设置里的主题推出来),Appearance深浅色,TextSize候选字号档,AppColorsApp 页面(不跟主题)。panel/:盖住候选条与键盘的面板。FunctionPanel/KeyboardPickerPanel/CatalogPanel(符号与表情)各一种,PanelKind面板种类,PanelActions是面板能做的事(服务实现);base/是共用的底子(PanelView表头与滚动、Tabs、ScrollState、Ink画笔、PanelIcons),clipboard/剪贴板与常用语(ClipboardPanel、拆词PiecesPanel),editor/浮在键盘上方接管打字的编辑条(FloatingEditor、常用语编辑框PhraseEditor)。VoicePanel是说话时盖上的语音面板。voice/:语音输入。VoiceInput是唯一入口(长按空格、工具栏话筒、底栏语音键),VoiceRecognizer识别方式的接口(占位UnavailableRecognizer、Rust 侧识别方EngineRecognizer),MicrophonePermissionActivity代输入法申请录音权限,VoiceConfig是「语音识别」页的配置(识别服务、计费方式、密钥密文,与云端大模型分开存)。translate/:快捷翻译,翻译条TranslateBar与流程QuickTranslate;系统文字选择菜单的「青简翻译」ProcessTextActivity;cloud/是云端配置、密钥(Android Keystore)与当前网络(Network,「只在 Wi-Fi 下使用」)。clipboard/:系统剪贴板的监听与图片的 content:// 出口。candidates/:键盘上方那一条。CandidateBarView在三种样子之间切:CandidateStrip候选(贴StripSource给的位图,拼音行钉住、候选随滚动)、Toolbar工具栏(浮在键盘上的圆角卡片,面板表头同样是浮起卡片)、ResizeHandle调高度手柄。popup/:ChoicePopup长按气泡,候选条(译词)与数字键(字母 / 数字)共用。settings/:Settings设置快照与BottomAction;App 各页分三块:home/启动页(MainActivity+ 三个AppPage:HomePage/VocabularyPage/MePage),page/二级页(KeyboardSettingsActivity/AppearanceActivity/DictionariesActivity/StatsActivity/AdvancedActivity/AboutActivity/VoiceSettingsActivity继承PageActivity),widget/控件积木(SettingsWidgets、TabBar、Wash渐变底、BarChart柱状图、ThemePreview主题预览)。
构建
需要 Android SDK(platform 36、NDK 29.0.13599879)、JDK 17 以上、Rust 目标与 cargo-ndk;不需要 Android Studio。
rustup target add aarch64-linux-android
cargo install cargo-ndk --locked
echo "sdk.dir=$HOME/Library/Android/sdk" > apps/android/local.properties
cd apps/android
./gradlew installDebug # 编 .so、放随包数据、打包、装到连着的设备
adb logcat -s qingjian # Rust 侧日志
preBuild 之前会跑两个任务:cargoNdk(cargo ndk 编 arm64-v8a 的 release .so)与 stageData
(data/generated/ 有 dict.qj 就带产品数据,没有退回 assets/sample/ 样例)。只编 arm64。
装好后打开「青简」,按页面上两步启用并切换输入法。
./gradlew assembleRelease 出 release 包;版本号取自 core/Cargo.toml,签名用的环境变量与发版流程见 docs/notes/release.md。
Rust 侧在本机就能测:cargo test -p qingjian-android。
约定
- JNI 句柄只在主线程用;每个出口拦 panic,出事返回 null,壳当空帧处理。
- 随包数据首次启动从 assets 解到
files/data/(.qj要 mmap,领域词库在dicts/下),装了新包才重解;学习数据在files/user/,导入的词库在files/user/dicts/。 - 解数据和装配在后台线程,没装好之前字母原样上屏。
- 密码、网址、邮箱、非文本输入框不过引擎。
- 不依赖
qingjian-platform:它带进的 native-tls / OpenSSL 在 Android 交叉编译过不了;云端直接引qingjian-predict并关缺省 feature、开rustls。