How to detect data changed in js from java with J2V8?

61 Views Asked by At

JS code

let obj = Native.getObj();
obj.width = 100;

kotlin code

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

nativeV8Obj.close()

class Native {
    fun getObj(): V8Object {
        return ...some v8-obj ...
    }
}

Then, execute js code. How to get notice in java layer once the code obj.width = 100; executed?

1

There are 1 best solutions below

0
On

After some testing, I found a solution. js proxy code

private val proxyJS = """
        function createProxy(obj) {
            return new Proxy(obj, {
                set: function (target, key, value) {
                    target[key] = value;
                    // call the native method update, notify value changed
                    target.update(key, value);
                    return true;
                }
            })
        }
    """.trimIndent()

At the v8 init and prepare stage, execute this script.

val v8 = V8.createV8Runtime()
v8.executeScript(proxyJS)

Then change Native's getObj method like below.

fun getObj(): V8Object {
    Log.d(TAG, "getObj")
    val func = v8.getObject("createProxy")
    Log.d(TAG, "func=$func")
    val obj = v8.newBindingV8Obj(Obj())  // this is a quick method of creating a binding V8Object, register methods in it
    // return the proxy object to v8 runtime
    return v8.executeObjectFunction("createProxy", V8Array(v8).push(obj))  
}
class Obj {
    companion object {
        private const val TAG = "Obj"
    }
    @J2V8Method
    fun update(vararg args: Any) {
        // This method will called when the js-obj's properties changed
        Log.d(TAG, "update args=${args.joinToString()}")
    }
}