文档章节

Android 在App和Java Web开发中的使用J2V8

IamOkay
 IamOkay
发布于 2015/09/10 23:14
字数 1078
阅读 2944
收藏 14

J2V8是基于webkit中内核js v8引擎的java 开源项目,实现了java与javaScript的互相调用,弥补了2种语言各自的缺陷

下载地址

http://mvnrepository.com/search?q=com.eclipsesource.j2v8

http://eclipsesource.com/blogs/2015/02/25/announcing-j2v8-2-0/


优点

1.可实现方法动态生成,注册和调用,可以解决java 方法爆棚问题

2.降低了交互难度,避免了使用webView

3.可直接调用大多数javascript api,让类似解析JSON变得更容易,方便

4.j2v8提供了多种数据结构,并实现了新的缓存数据存储方式

5.实现了动态脚本执行,实现了多线程

6.Javascript更容易调用Android代码层,开发语言使用Javascript+原生UI更容易开发Native App


缺点
  1. 由于使用了v8引擎,apk会变得更大

  2. 不支持Java类方法注册,不太支持Javascript的原型连中的call,apply

  3. 释放过程过于繁琐,内存不是ARC自动释放

  4. 不支持按脚本路径加载脚本,需要通过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<Thread> threads = new ArrayList<Thread>();
	        final List<Object> mergeSortResults = new ArrayList<Object>();
	        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<String> v8Map = new V8Map<String>();
		
		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.length;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;
	}


© 著作权归作者所有

IamOkay

IamOkay

粉丝 203
博文 483
码字总数 403074
作品 0
海淀
程序员
私信 提问
加载中

评论(3)

dimdim
dimdim
好东西,能动态更改界面对象么~0
IamOkay
IamOkay 博主

引用来自“一叶落影”的评论

怎么代替webview?
下载Android版本的j2v8 jar包,直接导入使用就行,但要记住,这种方式可能会阻塞线程,建议使用Handler+多线程实现
一叶落影
一叶落影
怎么代替webview?
J2V8 2.2 发布,V8 的 Java 封装版本

J2V8 2.2 发布,新增了两个重要的特性:1) 类型化数组 Typed Arrays ,2) 支持 64 位 Windows 系统。Typed Arrays 是一个连续的内存块类型视图。 Typed Arrays 举例: var myStuff = []; my...

oschina
2015/04/24
5.1K
6
OSChina 开源周刊第31期 —— Nginx 作为反向 Proxy 优化要点

每周技术抢先看,总有你想要的! 移动开发 【博客】IOS 中图片(UIImage)拉伸技巧 IOS 中图片拉伸处理的几种方法总结。详情 前端开发 【软件】AngularJS 自动完成 Angucomplete Angucomplete ...

OSC编辑部
2015/04/25
4.6K
8
OSChina 开源周刊第31期 —— Nginx 作为反向 Proxy 的优化要点

每周技术抢先看,总有你想要的! 移动开发 【博客】IOS 中图片(UIImage)拉伸技巧 IOS 中图片拉伸处理的几种方法总结。详情 前端开发 【软件】AngularJS 自动完成 Angucomplete Angucomplete ...

OSC编辑部
2015/04/25
259
0
OpenRASP 发布 0.20 版本,百度自适应安全产品

最近几年,Web攻击手段开始变得复杂,攻击面也越来越广。传统的安全防护手段,WAF、IDS 等等,大多是基于规则,已经不能满足企业对安全的基本需求。Gartner 在2014年提出了 "应用自我保护" 技...

OpenRASP
2017/10/26
484
1
开源轻量级 IM 框架 MobileIMSDK v3.0 发布!

一、更新内容简介 本次更新为主版本更新,更新内容包含了简化了消息发送目标的方式、支持Web版与APP版互通、优化了Protocal协议结构等主要升级,详细更新内容见“版本更新说明”部分。 重要提...

JackJiang-
2017/06/30
2.4K
11

没有更多内容

加载失败,请刷新页面

加载更多

面向对象编程

1、类和对象 类是对象的蓝图和模板,而对象是实例;即对象是具体的实例,类是一个抽象的模板 当我们把一大堆拥有共同特征的对象的静态特征(属性)和动态特征(行为)都抽取出来后,就可以定...

huijue
今天
8
0
redis异常解决 :idea启动本地redis出现 jedis.exceptions.JedisDataException: NOAUTH Authentication required

第一次安装在本地redis服务,试试跑项目,结果却出现nested exception is redis.clients.jedis.exceptions.JedisDataException: NOAUTH Authentication required错误,真是让人头疼 先检查一...

青慕
今天
10
0
Spring 之 IoC 源码分析 (基于注解方式)

一、 IoC 理论 IoC 全称为 Inversion of Control,翻译为 “控制反转”,它还有一个别名为 DI(Dependency Injection),即依赖注入。 二、IoC方式 Spring为IoC提供了2种方式,一种是基于xml...

星爵22
今天
25
0
Docker安装PostgresSql

Docker安装PostgresSql 拉取docker镜像 # docker pull postgres:10.1010.10: Pulling from library/postgres9fc222b64b0a: Pull complete 38296355136d: Pull complete 2809e135bbdb: Pu......

Tree
今天
8
0
内容垂直居中

方法一: 采用上下 padding 形式,将内容放置在垂直居中 .line { padding: 2% 0; text-align: center; height: 5px;} <div class="line"> 内容垂直居中</div> 方法二: 采......

低至一折起
今天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部