Codename One 这周同时落地了两个小特性。都很小,都直接在内核里,不用额外加cn1lib,不用写原生接口。它们沿用Codename One一贯的设计:一套可移植Java API,平台支持就调用原生,不支持就退到一个还行的纯Java实现。一个是安全相关的设备完整性检测,另一个是让应用向用户要评分又不至于烦到他们。两个功能毫无关系,恰好同一周发布,就放在一起聊聊。
先说设备完整性。它的官方位置在 com.codename1.security.DeviceIntegrity ,本质是一个便携的运行时自我保护(RASP)和远程证明API。这东西不是给所有应用准备的,Codename One 官方说得也很直接:做银行、支付、任何需要检测运行环境是否被篡改的应用才需要它。如果你在做一个菜谱浏览器,那这段可以跳过。Codename One 本来就有一些银行客户,也一直在加固自己来满足这些客户的要求,这个API就是其中一部分产出。
![]()
API 提供了四项能力,每一项都用一个零代码的构建提示来启用,还有对应的运行时方法让开发者用Java去调用和判断。设计思路模仿了已有的 isJailbrokenDevice() 这一套检测链路。接口通过 Display 暴露,默认在 CodenameOneImplementation 里标记为“不支持”,然后在Android和iOS端口各自覆盖。Android端通过反射调用Play Integrity和RootBeer,确保端口jar包保持零依赖,仅当构建提示把对应SDK打进classpath时才生效。iOS端 App Attest 走 DCAppAttestService ,用 CN1_USE_APP_ATTEST 宏控制,编译时没打开这个宏就进到 #else 存根分支,不导入也不链接 DeviceCheck.framework 。异步结果通过静态回调返回,跟 IOSBiometrics 的返回形状一样。
拿一个完整性令牌的调用很简短:先从自己后端拿一个nonce,然后调用 requestIntegrityToken ,收到token后直接扔回自己的服务器验证:
String nonce = myBackend.fetchIntegrityNonce();DeviceIntegrity.requestIntegrityToken(nonce).ready(token -> {myBackend.verifyIntegrity(token);还有一个更轻量、不需要一次网络往返的信号:
if (DeviceIntegrity.isDeviceCompromised()) {for (String reason : DeviceIntegrity.getCompromiseReasons()) {Log.p("RASP信号: " + reason);这里有一个非常关键的结论:客户端不是安全边界。证明令牌(attestation token)是不透明的,API只是把签名过的令牌交给你的应用,但最终要不要放行,这个决定必须发生在你的后端,因为验证密钥只在后端,设备本身没有话语权。如果你以为 isDeviceCompromised() 返回 false 就万事大吉,那就把安全边界推给了一个不可信的环境。凡是做完整性检测的,都该把这个认知刻在脑子里。
同样在这一周发布的还有一个评分请求特性,具体细节没有展开,但设计理念很清楚:在不惹恼用户的前提下,引导用户去给应用打分。Codename One 把它做得非常克制,不会在用户用得好好的时候突然弹一个全屏评分框。至于它究竟怎么判断时机、怎么控制频率,原文没有进一步说明,但至少从“不烦人”这个定位来看,开发者不需要再去折腾原生的评分弹窗逻辑了,直接用这套API就行。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.