Wry Android 查询 Cookie 后闪退:getCookie(...) must not be null
没有 Cookie 的 URL 可以让 Android CookieManager 返回空引用,Wry 的非空 Kotlin 返回值随后触发主线程异常。Rust 收到空列表,也可能还没有观察到崩溃。
Android 应用调用 cookies_for_url 后立即闪退,logcat 显示 java.lang.NullPointerException: getCookie(...) must not be null,堆栈落在生成的 RustWebView.getCookies。先检查目标 URL 当时是否根本没有 Cookie。
Wry 0.55.1、Tauri 2.11.5 的具体设备故障中,一个 WebView 就足以触发;不需要第二个窗口,也不要求为窗口创建新的数据目录。已有 Cookie 的域名可以正常返回,换成没有 Cookie 的 URL 就进入空返回路径。
Kotlin 承诺非空,平台却返回了 null
Wry 的 Android 桥接方法声明返回 String,并直接返回 CookieManager.getCookie(url)。当平台返回 null 时,Kotlin 的非空检查会抛出异常;方法在 Android 主线程执行,未处理的异常最终使应用退出。
截至 2026 年 10 月 24 日,正式 Wry 0.57.1 的该方法仍保留这条直接返回路径,不能把更新到 0.57.1 当成已经修好这一问题的依据。它也不是所有 WebView 闪退的答案,应以具体异常和 getCookies 堆栈为准。
Rust 一侧甚至可能先收到空列表,再由仍挂起的 Java 异常导致主线程退出。因此,“Rust 返回 Ok,数量为零”不能单独作为验收。只在 Rust 的 Result 上处理 Err,或给 Rust 调用包 catch_unwind,都拦不住这条 Kotlin 空值检查。
在桥接方法中明确表示“没有 Cookie”
有能力维护依赖补丁的项目,可以在对应版本的 Android Kotlin 桥接源中给空返回提供空字符串:
fun getCookies(url: String): String {
val cookieManager = CookieManager.getInstance()
return cookieManager.getCookie(url) ?: ""
}
这段代码保留“查询当前 URL 的 Cookie”语义,不会创建登录态。还需核对同一版本 Rust 桥接对空字符串的解析结果确实是空列表,避免只把异常换成解析错误。
修改应放进项目可追踪的依赖补丁或受控分支,并锁定构建来源。不要只改某次构建目录中的生成 Kotlin 文件:清理或重新生成 Android 工程时,它可能被旧依赖模板覆盖。经由 Tauri 间接使用 Wry 时,还应确认实际解析到的 Wry 版本和进入 Android 包的生成结果,不能只检查桌面依赖。
暂时不能维护补丁时,可停用受影响版本中的该查询入口,按应用已有登录流程判断会话结果。不要先给域名写一个虚假 Cookie 来“保证非空”,也不要清空所有站点 Cookie;这些做法会改动用户会话,仍无法保证下一次查询一定有值。
验收必须观察调用之后的主线程
在可控 WebView 中分别准备有 Cookie 的 URL 和确实没有 Cookie 的 URL。前者应保留正常解析,后者返回空列表;随后让主线程继续处理页面和交互,确认没有延后出现的 NullPointerException。
保留日志中的查询 URL 范围与调用前后标记,Cookie 值不要写入共享日志。不同域名、路径、Secure 或分区条件会影响某个 URL 是否能取得 Cookie,但没有匹配项本来就应是正常结果,不能把“用户从未访问该域名”当成不允许查询的前提。
若要撤回依赖补丁,连同被停用或恢复的调用入口一并处理,重新验证 Android 实际安装包。编译通过和 Rust 函数返回,都还不足以证明这条跨语言调用安全结束。


