You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过J2V8在Java层监听JS对象属性的变更?

在Java/Kotlin层捕获V8对象属性变更通知

针对你给出的JS与Kotlin代码场景,当JS执行obj.width = 100时,要在Java层获取属性变更通知,核心是利用V8引擎的**Accessor(属性访问器)**机制,给目标V8对象的width属性绑定自定义的setter回调,具体实现如下:

调整Kotlin代码实现

修改Native类的getObj方法,在创建返回的V8Object时,为width属性注册getter和setter回调,当JS侧修改属性值时,会触发setter中的Java层逻辑:

val native = Native()
val nativeV8Obj = V8Object(v8)
nativeV8Obj.registerJavaMethod(native, "getObj", "getObj", emptyArray())
v8.add("Native", nativeV8Obj)

// 注意:nativeV8Obj.close()不要在初始化阶段调用,否则后续JS无法访问Native对象
// nativeV8Obj.close() 需移到V8引擎销毁前执行

class Native {
    fun getObj(): V8Object {
        val v8Obj = V8Object(v8)
        
        // 注册width属性的访问器:getter负责返回值,setter捕获变更
        v8Obj.registerAccessor(
            "width",
            // Getter回调:返回存储的实际值
            V8FunctionCallback { receiver, _ ->
                receiver?.get("width_internal") ?: v8.createUndefined()
            },
            // Setter回调:捕获属性变更,这里就是通知触发点
            V8FunctionCallback { receiver, parameters ->
                val newValue = parameters?.first()
                // 用内部隐藏属性存储实际值,避免直接访问width导致循环调用
                receiver?.set("width_internal", newValue)
                // 这里编写你的变更处理逻辑,比如打印日志、通知其他组件等
                println("width属性已变更为: ${newValue?.toString()}")
                null
            },
            false // 是否启用严格模式,按需设置
        )
        
        // 初始化width的默认值
        v8Obj.set("width_internal", 0)
        return v8Obj
    }
}

关键说明

  • Accessor机制:V8的registerAccessor方法允许为属性绑定自定义的读写逻辑,当JS侧对属性进行赋值操作时,会直接触发Java层的setter回调,从而实现变更通知。
  • 内部存储属性:使用width_internal作为实际值的存储容器,避免在getter/setter中直接访问width属性导致无限循环调用。
  • 资源管理:注意不要在初始化阶段就调用nativeV8Obj.close(),否则JS侧将无法访问Native对象;需在V8引擎销毁前统一关闭所有V8Object实例,防止内存泄漏。
  • 多属性监听:如果需要监听多个属性,重复调用registerAccessor为每个属性绑定对应的getter/setter即可。

内容的提问来源于stack exchange,提问作者boybeak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:50:18