J2V8是基于webkit中内核js v8引擎的java 开源项目,实现了java与javaScript的互相调用,弥补了2种语言各自的缺陷
下载地址
优点
1.可实现方法动态生成,注册和调用,可以解决java 方法爆棚问题
2.降低了交互难度,避免了使用webView
3.可直接调用大多数javascript api,让类似解析JSON变得更容易,方便
4.j2v8提供了多种数据结构,并实现了新的缓存数据存储方式
5.实现了动态脚本执行,实现了多线程
6.Javascript更容易调用Android代码层,开发语言使用Javascript+原生UI更容易开发Native App
缺点
由于使用了v8引擎,apk会变得更大
不支持Java类方法注册,不太支持Javascript的原型连中的call,apply
释放过程过于繁琐,内存不是ARC自动释放
不支持按脚本路径加载脚本,需要通过IO流转为字符串才能将脚本加入
一.代码展示
好了,以上是J2V8的相关信息,下面欣赏一下这个开源项目的魅力
package org.twt.zipjar.test;import java.util.ArrayList;import java.util.List;import com.eclipsesource.v8.V8;import com.eclipsesource.v8.V8Array;import com.eclipsesource.v8.V8Object;import com.eclipsesource.v8.utils.V8Map;import com.eclipsesource.v8.utils.V8ObjectUtils;import com.eclipsesource.v8.utils.V8Runnable;import com.eclipsesource.v8.utils.V8Thread;public class J2V8TestCase { public static void main(String[] args) { testMap(); } //多线程测试 public void testMultiV8Threads() throws InterruptedException { final V8 v8 = V8.createV8Runtime(); final List
threads = new ArrayList
(); final List
mergeSortResults = new ArrayList(); for (int i = 0; i < 10; i++) { V8Thread t = new V8Thread(new V8Runnable() { @Override public void run(V8 v8) { synchronized (threads) { V8Array data = new V8Array(v8); int max = 100; for (int i = 0; i < max; i++) { data.push(max - i); } V8Array parameters = new V8Array(v8).push(data); mergeSortResults.add(V8ObjectUtils.toList(parameters)); parameters.release(); data.release(); } } }); threads.add(t); } for (Thread thread : threads) { thread.start(); } for (Thread thread : threads) { thread.join(); } } //动态定义函数 private static void testDeclareFunctions() { V8 v8 = V8.createV8Runtime(); v8.executeVoidScript("function getPerson(first, last, age) {return {'first':first, 'last':last, 'age':age};}"); V8Array parameters = new V8Array(v8); parameters.push("John"); parameters.push("Smith"); parameters.push(7); V8Object result = v8.executeObjectFunction("getPerson", parameters); parameters.release(); result.release(); } //测试MAP private static void testJsMap() { V8 v8 = V8.createV8Runtime(); V8Map
v8Map = new V8Map
(); V8Object v8Object = new V8Object(v8); v8Map.put(v8Object, "foo"); v8.registerResource(v8Map); System.out.println(v8Map.get(v8Object)); v8Object.release(); v8.release(true); } //测试数组 private static void testJSArray() { V8 v8 = V8.createV8Runtime(); V8Array param = new V8Array(v8); V8Array arrAList = new V8Array(v8).push(0).push("0"); V8Array arrBList = new V8Array(v8).push(1).push("1"); param.push(1).push(arrAList).push(arrBList).push("a"); //[1, [0, 0], [1, 1], a] System.out.println(V8ObjectUtils.toList(param)); arrAList.release(); arrBList.release(); param.release(); v8.release(); } //测试JSON private static void testJSON() { V8 v8 = V8.createV8Runtime(); V8Object v8Object = new V8Object(v8).add("foo", "bar") .add("name", "zhangsan") .add("age", 20); V8Object json = v8.getObject("JSON"); V8Array params = new V8Array(v8).push(v8Object); String result = (String) json.executeFunction("stringify", params); V8Array params2 = new V8Array(v8).push(result); V8Object result2 = json.executeObjectFunction("parse", params2); System.out.println(result); System.out.println(result2.getString("name")); params.release(); params2.release(); result2.release(); json.release(); v8Object.release(); v8.release(); } //测试数据缓存 private static void testCache() { V8 v8 = V8.createV8Runtime(); v8.add("name", "zhangsan"); System.out.println(v8.get("name")); v8.release(); } //测试调用java方法 private static void testJavaNativeMethod() { V8 v8 = V8.createV8Runtime(); v8.registerJavaMethod(new J2V8TestCase(), "print", "native_print",new Class[]{String.class}); StringBuilder sb = new StringBuilder(); sb.append("var str='Hello World';"); sb.append("native_print(str);"); v8.executeVoidScript(sb.toString()); v8.release(); } //执行脚本 private static void executeArrayScript() { V8 v8 = V8.createV8Runtime(); V8Array result = v8.executeArrayScript("var buffer = new ArrayBuffer(256);\n" + "var i32 = new Int32Array(buffer);\n" + "i32[0] = 1;\n" + "i32[1] = 3;\n" + "i32[2] = i32[0] + i32[1];\n" + "i32;"); int[] ints = result.getIntegers(0, 3); result.release(); v8.release(); } public void print(String s){ System.out.println(s); }}
二.脚本加载
为了更方便的执行脚本,我们可以将脚本单独提取出来,例如以下我写的JS脚本,增强原生JS Math对象
test_j2v8_javascript.js
var StrictMathHelper = function(){ }StrictMathHelper.prototype = Math;/** *加总 */StrictMathHelper.prototype.sum = function(){ var args = arguments; if(args.length==0) { return 0; } if(Array.isArray(arguments[0])) { args = arguments[0]; } for(var i=1;i
然后我们通过如下方式加载
public static Object testLoadScript() { Object result = null; try { File scriptFile = new File("test_j2v8_javascript.js"); BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(scriptFile))); StringBuffer sb = new StringBuffer(); String strLine = null; while((strLine=br.readLine())!=null) { sb.append(strLine).append("\r\n");//为了保证js的严格“行”属性,这里主动追加\r\n } br.close(); V8 v8 = V8.createV8Runtime(); v8.executeScript(sb.toString()); V8Object strictMath = v8.getObject("StrictMath"); V8Array args = new V8Array(v8).push(0) .push(1) .push(2) .push(3) .push(4) .push(5) .push(6) .push(7) .push(8) .push(9); V8Array params = new V8Array(v8).push(args); result = strictMath.executeDoubleFunction("sum", params); args.release(); params.release(); strictMath.release(); v8.release(); } catch (Exception e) { e.printStackTrace(); return result; } return result; }