- java调用JavaScript函数(一个参数)
/**
-
除了执行脚本外,Java还可使用J2V8调用JavaScript函数。
-
函数可以是全局函数,也可以附加到另一个Object,并且可以选择返回结果。
*/
private void exeJsFunction() {
V8 runtime = V8.createV8Runtime();
runtime.executeVoidScript(“”
-
“var hockeyTeam = {\n”
-
“name : ‘WolfPack’,\n”
-
“players : [],\n”
-
“addPlayer : function(player) {\n”
-
" this.players.push(player);\n"
-
" return this.players.length;\n"
-
“}\n”
-
“}\n”);
V8Object hockeyTeam = runtime.getObject(“hockeyTeam”);
V8Object player1 = new V8Object(runtime).add(“name”, “John”);
V8Object player2 = new V8Object(runtime).add(“name”, “Huang”);
//获取palyers数组
V8Array players = hockeyTeam.getArray(“players”);
players.push(player1).push(player2);
//创建对象为addPlayer方法传值
V8Object player3 = new V8Object(runtime).add(“name”, “Add”);
//注意:将值封装到V8Array中传给addPlayer方法(只有一个参数,因此push一个值)
V8Array push = new V8Array(runtime).push(player3);
int size = hockeyTeam.executeIntegerFunction(“addPlayer”, push);
//JS result size = 3
Log.e(TAG, "JS result size = "+size);
players.close();
player1.close();
player2.close();
player3.close();
push.close();
hockeyTeam.release();
runtime.close();
}
- java调用JavaScript函数(多个参数)
/**
- java调用JavaScript函数(多个参数)
*/
private void exeJsFunctionBase() {
V8 runtime = V8.createV8Runtime();
runtime.executeVoidScript(“” +
“function add(a,b){” +
" return a + b" +
“}”);
V8Array v8Array = new V8Array(runtime).push(10).push(40);
int add = runtime.executeIntegerFunction(“add”, v8Array);
Log.e(TAG, "JS result add = "+add);
v8Array.close();
runtime.close();
}
- java调用JavaScript函数(V8Function调用call)
/**
-
java调用JavaScript函数(V8Function调用call)
-
在JS中万物皆对象,函数也不例外。在 j2v8 中,一切 js 对象都用 V8Object 表示,
-
我们可以直接将其强制转换为 V8Function。
-
-
V8Function 表示的就是一个 js 函数对象,它拥有 call() 方法可以直接被调用。
*/
private void exeJsFunctionBaseCall() {
V8 runtime = V8.createV8Runtime();
runtime.executeVoidScript(“” +
“function add(a,b){” +
" return a + b" +
“}”);
//先判断 add是不是一个函数
if (runtime.getType(“add”)==V8.V8_FUNCTION){
V8Array push = new V8Array(runtime).push(25).push(50);
Object add = runtime.getObject(“add”);
if (add instanceof V8Function){
V8Function addFunction = (V8Function) add;
int addResult = (int) addFunction.call(null, push);
Log.e(TAG, "JS result addResult = "+addResult);
push.close();
addFunction.close();
}
}
runtime.close();
}
- Js 调用 Java function(注册 Java 回调 —— 接口方式)
/**
-
要注册函数到 js,首先要创建一个类,并实现 JavaCallback 接口(如果 java 函数没有返回值,则实现 JavaVoidCallback 接口即可)。
-
这两个接口均有一个 invoke(V8Object receiver, V8Array parameters) 函数,
-
当被 js 调用时就会触发,这样就可执行 java 代码了
*/
private JavaVoidCallback javaVoidCallback= new JavaVoidCallback() {
/**
-
receiver 是此函数被调用时所基于的对象
-
parameters 是传入的参数列表,表现为一个 V8数组,可以从中提取 js 传入的各个参数。
-
在这个例子中,print 不再基于 Global,而是基于 array[i] 被调用的,
-
因此 array[i] 将被传入 java 作为 receiver. 最终 java 将依次输出 AA says Hi., BB says Hi., CC says Hi…
-
@param receiver
-
@param parameters
*/
@Override
public void invoke(V8Object receiver, V8Array parameters) {
Log.e(TAG,receiver.getString(“first”)+parameters.get(0)+" "+parameters.get(1));
// 必须释放从参数列表中检索到的所有V8Object,因为它们是由于方法调用而返回给您的。
for (int i = 0; i < parameters.length(); i++) {
Object o = parameters.get(i);
if (o instanceof Readable){
((Releasable) o).close();
}
}
receiver.close();
parameters.close();
}
};
/**
-
Js 调用 Java function(注册 Java 回调)
-
1.接口方式
-
-
java 函数必须先注册到 js 才可以被调用
*/
private void JsCallJavaViaInterface() {
V8 runtime = V8.createV8Runtime();
runtime.registerJavaMethod(javaVoidCallback,“print”);
runtime.executeVoidScript(“” +
“var array = [{first:‘AA’}, {first:‘BB’}, {first:‘CC’}];\n” +
“for ( var i = 0; i < array.length; i++ ) {\n” +
" print.call(array[i], " says Hi.“,“Second”);” +
“}”);
runtime.close();
}
- Js 调用 Java function(反射)
private class AndroidConsole {
public void log( String message) {
Log.e(TAG, "[INFO] " + message);
}
public void error( Integer message) {
Log.e(TAG, "[ERROR] " + message);
}
}
/**
-
Js 调用 Java function
-
2.反射
-
-
java 函数必须先注册到 js 才可以被调用
-
-
在本例中,通过反射注册了现有 java 对象的方法。必须指定Java对象、方法的名称和参数列表。
-
并且此处不是直接注册为全局函数,而是先创建了一个名为 console 的 js 对象,把函数注册到了此对象上,
-
-
不难发现,通过接口方式注册,参数可以是动态的
-
而通过反射注册,参数必须明确指定并且与 java 参数严格匹配,若参数不匹配则会异常。
*/
private void jsCallJavaViaReflection() {
V8 runtime = V8.createV8Runtime();
AndroidConsole androidConsole = new AndroidConsole();
V8Object v8Object = new V8Object(runtime);
runtime.add(“console”,v8Object);
//参数1:对象索引(这里是AndroidConsole对象) 参数2:java方法名,参数三:js里面写的方法名 参数4:方法的参数类型 个数
v8Object.registerJavaMethod(androidConsole,“log”,“jlog”,new Class<?>[]{String.class});
v8Object.registerJavaMethod(androidConsole,“error”,“jerr”,new Class<?>[]{Integer.class});
// 然后可以直接在 js 中调用 console.jlog('hello, world')
与 console.jerr('hello, world')
了。
runtime.executeScript(“console.jlog(‘hello, world’);”);
runtime.executeScript(“console.jerr(100);”);
v8Object.close();
runtime.close();
}
- Js 调用 Java function(反射2)——重要
public void getJsText(String text){
Log.e(TAG, "[TEXT] " + text);
}
/**
-
Js 调用 Java function
-
2.反射
-
-
java 函数必须先注册到 js 才可以被调用
-
-
在本例中,通过反射注册了现有 java 对象的方法。必须指定Java对象、方法的名称和参数列表。
-
并且此处不是直接注册为全局函数,而是先创建了一个名为 console 的 js 对象,把函数注册到了此对象上,
-
-
不难发现,通过接口方式注册,参数可以是动态的
-
而通过反射注册,参数必须明确指定并且与 java 参数严格匹配,若参数不匹配则会异常。
*/
private void jsCallJavaViaReflection2() {
V8 runtime = V8.createV8Runtime();
//自动内存管理
MemoryManager scope = new MemoryManager(runtime); // 实例化 MemoryManager
V8Object v8Object = new V8Object(runtime);
runtime.add(“jsMethod”,v8Object);
//参数1:context(当前Activity对象) 参数2:java方法名,参数三:js里面写的方法名 参数4:方法的参数类型 个数
v8Object.registerJavaMethod(this,“getJsText”,“setText”,new Class<?>[]{String.class});
runtime.executeScript(“jsMethod.setText(‘我是JS方法’);”);
//在用了自动内存管理后,代码会变得非常简洁
scope.release();
}
- Js 调用 Java function(无需注册将 js 执行 java 函数)
/**
-
在 j2v8 V4 中,增加了新的方式,可以无需注册将 js 执行 java 函数。
-
-
在之前的例子中,java 函数必须先注册到 js 才可以被调用。
-
试想这样一个需求:js 有一个函数,需要传入一个回调函数。
-
此时希望 java 来执行此函数,那么参数应该怎么传递呢?之前,是没有办法,但是现在有了。
最后
考虑到文章的篇幅问题,我把这些问题和答案以及我多年面试所遇到的问题和一些面试资料做成了PDF文档
喜欢的朋友可以关注、转发、点赞 感谢!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
。
-
-
在之前的例子中,java 函数必须先注册到 js 才可以被调用。
-
试想这样一个需求:js 有一个函数,需要传入一个回调函数。
-
此时希望 java 来执行此函数,那么参数应该怎么传递呢?之前,是没有办法,但是现在有了。
最后
考虑到文章的篇幅问题,我把这些问题和答案以及我多年面试所遇到的问题和一些面试资料做成了PDF文档
[外链图片转存中…(img-kPg1F5gf-1714502971691)]
[外链图片转存中…(img-JEwuwtwY-1714502971692)]
喜欢的朋友可以关注、转发、点赞 感谢!
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!