【Android】不使用WebView来执行Javascript脚本(Rhino)
来源:互联网 发布:淘宝标题营销词位置 编辑:程序博客网 时间:2024/05/16 17:26
【Android】不使用WebView来执行Javascript脚本(Rhino)
前言
动态执行脚本能有效的降低重要功能硬编码带来的问题,尤其是依赖于第三方的应用,可以通过动态脚本+在线参数(例如友盟在线参数)再不更新应用的情况下升级功能。
声明
欢迎转载,但请保留文章原始出处:)
博客园:http://www.cnblogs.com
农民伯伯: http://over140.cnblogs.com
正文
一、准备
项目地址:https://developer.mozilla.org/en-US/docs/Rhino
项目说明:由Mozilla开发,是 JavaScript 一种基于Java的实现。
项目使用:把js.jar拷贝到项目工程既可。
二、 代码
主要实现了从Java中执行js中的函数、从js中调用Java中的方法,代码:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text1 = (TextView) findViewById(android.R.id.text1);
TextView text2 = (TextView) findViewById(android.R.id.text2);
text1.setText(runScript(JAVA_CALL_JS_FUNCTION, "Test", new String[] {}));
text2.setText(runScript(JS_CALL_JAVA_FUNCTION, "Test", new String[] {}));
}
/** Java执行js的方法 */
private static final String JAVA_CALL_JS_FUNCTION = "function Test(){ return '农民伯伯 java call js Rhino'; }";
/** js调用Java中的方法 */
private static final String JS_CALL_JAVA_FUNCTION = //
"var ScriptAPI = java.lang.Class.forName(\"" + MainActivity.class.getName() + "\", true, javaLoader);" + //
"var methodRead = ScriptAPI.getMethod(\"jsCallJava\", [java.lang.String]);" + //
"function jsCallJava(url) {return methodRead.invoke(null, url);}" + //
"function Test(){ return jsCallJava(); }";
/**
* 执行JS
*
* @param js js代码
* @param functionName js方法名称
* @param functionParams js方法参数
* @return
*/
public String runScript(String js, String functionName, Object[] functionParams) {
Context rhino = Context.enter();
rhino.setOptimizationLevel(-1);
try {
Scriptable scope = rhino.initStandardObjects();
ScriptableObject.putProperty(scope, "javaContext", Context.javaToJS(MainActivity.this, scope));
ScriptableObject.putProperty(scope, "javaLoader", Context.javaToJS(MainActivity.class.getClassLoader(), scope));
rhino.evaluateString(scope, js, "MainActivity", 1, null);
Function function = (Function) scope.get(functionName, scope);
Object result = function.call(rhino, scope, scope, functionParams);
if (result instanceof String) {
return (String) result;
} else if (result instanceof NativeJavaObject) {
return (String) ((NativeJavaObject) result).getDefaultValue(String.class);
} else if (result instanceof NativeObject) {
return (String) ((NativeObject) result).getDefaultValue(String.class);
}
return result.toString();//(String) function.call(rhino, scope, scope, functionParams);
} finally {
Context.exit();
}
}
public static String jsCallJava(String url) {
return "农民伯伯 js call Java Rhino";
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text1 = (TextView) findViewById(android.R.id.text1);
TextView text2 = (TextView) findViewById(android.R.id.text2);
text1.setText(runScript(JAVA_CALL_JS_FUNCTION, "Test", new String[] {}));
text2.setText(runScript(JS_CALL_JAVA_FUNCTION, "Test", new String[] {}));
}
/** Java执行js的方法 */
private static final String JAVA_CALL_JS_FUNCTION = "function Test(){ return '农民伯伯 java call js Rhino'; }";
/** js调用Java中的方法 */
private static final String JS_CALL_JAVA_FUNCTION = //
"var ScriptAPI = java.lang.Class.forName(\"" + MainActivity.class.getName() + "\", true, javaLoader);" + //
"var methodRead = ScriptAPI.getMethod(\"jsCallJava\", [java.lang.String]);" + //
"function jsCallJava(url) {return methodRead.invoke(null, url);}" + //
"function Test(){ return jsCallJava(); }";
/**
* 执行JS
*
* @param js js代码
* @param functionName js方法名称
* @param functionParams js方法参数
* @return
*/
public String runScript(String js, String functionName, Object[] functionParams) {
Context rhino = Context.enter();
rhino.setOptimizationLevel(-1);
try {
Scriptable scope = rhino.initStandardObjects();
ScriptableObject.putProperty(scope, "javaContext", Context.javaToJS(MainActivity.this, scope));
ScriptableObject.putProperty(scope, "javaLoader", Context.javaToJS(MainActivity.class.getClassLoader(), scope));
rhino.evaluateString(scope, js, "MainActivity", 1, null);
Function function = (Function) scope.get(functionName, scope);
Object result = function.call(rhino, scope, scope, functionParams);
if (result instanceof String) {
return (String) result;
} else if (result instanceof NativeJavaObject) {
return (String) ((NativeJavaObject) result).getDefaultValue(String.class);
} else if (result instanceof NativeObject) {
return (String) ((NativeObject) result).getDefaultValue(String.class);
}
return result.toString();//(String) function.call(rhino, scope, scope, functionParams);
} finally {
Context.exit();
}
}
public static String jsCallJava(String url) {
return "农民伯伯 js call Java Rhino";
}
}
三、下载
SampleRhino.zip(2013-12-05)
四、相关文章
4.1Embed JavaScript in Android Java Code with Rhino
4.2JavaScript (Rhino) on Android
4.3纯java 的javascript引擎:rhino
4.4深入浅出Rhino:Java与JS互操作
五、其他
注意,混淆的时候js.jar可能混淆不过去,请参照文章4.1的方法。
分类: 3、Android
标签: android动态脚本, android Rhino, android 执行js, android 不使用WebView执行js
0 0
- 【Android】不使用WebView来执行Javascript脚本(Rhino)
- 【Android】不使用WebView来执行Javascript脚本(Rhino)
- Mozilla Rhino:使用java语言来解释和执行javascript脚本(转)
- Mozilla Rhino:使用java语言来解释和执行javascript脚本(转)
- Android JS解析引擎 Rhino 使用笔记(不借助webview)
- 脚本引擎Rhino执行javascript代码
- JavaScript脚本引擎Rhino
- JavaScript -Rhino 使用
- android webview setTimeout不执行
- 为什么webview.loadUrl("javascript:function() ")不执行?
- 在java中利用rhino执行javascript
- 安卓的WebView不弹新窗口使用自有窗口加载及加载后执行javascript
- android WebView shouldOverrideUrlLoading 不执行问题
- android webview js不执行原因解析
- 使用JavaApi执行javascript脚本
- java中使用javascript Rhino 引擎
- rhino解析器执行js脚本,console输出中文乱码
- Android WebView使用Javascript详解
- Android使用newInstance()实例化fragment&setArguments()传递参数
- STM32 boot跳转到APP的Jump_Address()分析
- 黑客们是如何查看远程电脑win7系统进程?
- android 架构
- String笔试题
- 【Android】不使用WebView来执行Javascript脚本(Rhino)
- leetcode 11. Container With Most Water
- django主键的使用
- 图像检索:几种基于纹理特征的图像检索算法
- Android Studio项目目录结构介绍
- thinkphp下mongo的操作
- iOS9适配 之 关于info.plist 第三方登录 添加URL Schemes白名单
- test
- struct结构体初始化