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
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
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
{
args[0] = args[0]+args[i];
}
return args[0];
};
//四舍五入,保留小数位
StrictMathHelper.prototype.roundFixed = function(a,n)
{
if(!isNaN(a))
{
return a.toFixed(n);
}
};
StrictMathHelper.prototype.fn = StrictMathHelper.prototype;
StrictMathHelper.prototype.fn.extend = function(o)
{
var that = this;
if(o instanceof Object)
{
for(var name in o)
{
if(typeof(name)=='string' && (o[name] instanceof Function) && typeof(that[name])==='undefined')
{
that[name] = o[name];
}
}
}
};
StrictMathHelper.create = function()
{
return new StrictMathHelper();
};
var StrictMath = StrictMathHelper.create();
然后我们通过如下方式加载
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;
}