Kobo 现在可以运行应用程序了。
Kobo can run apps now

原始链接: https://bandarlabs.github.io/Cobalt/

Kobo SDK 为在电子墨水(E-ink)设备上构建应用提供了声明式框架。它负责处理布局、电子墨水刷新周期、生命周期事件和返回导航等核心复杂问题,使开发者能够专注于应用逻辑。 主要特性包括: * **功能门控访问**:应用不直接访问硬件,而是请求资源(网络、存储等),由运行时安全地处理权限结果。 * **强大的工具链**:包含用于布局诊断的模拟器,支持异步操作(HTTPS、可取消任务)以及原子键值存储。 * **部署**:应用以已签名的静态 ARMv7 二进制文件形式交付,通过简单的命令行接口(`kobo new`、`kobo dev`)集成到开发工作流中。 该 SDK 使用基于特征(trait)的模式(`KoboApp`),开发者通过 `ScreenBuilder` 定义状态并实现 UI 更新。这种架构确保了设备的独特显示限制和导航模式由运行时自动处理,同时让开发者能够编写简洁、模块化的代码。

最近的一篇 Hacker News 帖子指出,Kobo 电子阅读器现已支持第三方应用程序,这一进展受到了社区的高度热情回应。用户尤其对添加自定义功能的潜力感到兴奋,例如改进笔记管理和引文回顾工具。 这场讨论反映了电子阅读器社区中存在的广泛分歧。尽管一些 Kindle 用户对 Kobo 设备新获得的灵活性表示羡慕,但另一些人则认为电子阅读器应当保持专注阅读、功能单一的初衷。此次更新的支持者反驳称,能够运行应用程序并不代表强制使用,这提供了一种可选的实用性,而非造成混乱。一些用户还对 Kobo 未来可能采取的限制措施表示担忧,而另一些人则借此机会批评了未经越狱的 Kindle 设备中过多的广告。总体而言,社区认为这是电子阅读器定制化进程中一个令人印象深刻的里程碑。
相关文章

原文

The SDK

Implement KoboApp, describe screens declaratively, and the runtime handles layout, e-ink refresh planning, Back navigation and lifecycle.

Apps don't open device resources; they ask. Network, storage, audio, frontlight and Wi-Fi are capability-gated, and a refusal comes back as a value the app can handle.

E-ink UI
Text, tiles, dialogs, keyboards, pagination, partial refresh planning

Simulators
Browser and runtime simulators with layout diagnostics

Async work
HTTPS, ranged downloads, cancellable tasks, scheduled wakes

State
Atomic per-app keyed storage

Shipping
Signed static ARMv7 binaries, published when an app PR merges

kobo new my-app
cd my-app
kobo dev

Read the SDK docs

use kobo_sdk::{
    ActionId, Context, KoboApp, ScreenBuilder,
};

#[derive(Default)]
struct Hello { taps: u32 }

impl KoboApp for Hello {
    fn on_start(&mut self, ctx: &mut Context) {
        self.show(ctx);
    }

    fn on_action(
        &mut self, ctx: &mut Context, a: ActionId,
    ) {
        if a == kobo_sdk::action_id("tap") {
            self.taps += 1;
        }
        self.show(ctx);
    }
}

impl Hello {
    fn show(&self, ctx: &mut Context) {
        let screen = ScreenBuilder::new("hello")
            .top_bar("Hello")
            .heading(format!("{} taps", self.taps))
            .button("tap", "Tap me")
            .build();
        ctx.set_screen(screen);
    }
}

fn main() {
    let app = Hello::default();
    let _ = kobo_sdk::run("hello", app);
}
联系我们 contact @ memedata.com