Android中JavaScript和Native之间的Bridge

转载 2016年08月29日 11:19:27

原文地址:http://rensanning.iteye.com/blog/2043049



为什么手机浏览器或者WebView中不能执行JavaScript调用本地API,而在HTML5混合式应用中却能执行? 


JavaScript调用本地API大概有4种方法: 

(1)addJavascriptInterface/@JavascriptInterface 
Android的WebView类的标准接口。 
Java代码  收藏代码
  1. webView.addJavascriptInterface(new JSHandler(this), "Bridge");  
  2.   
  3. class JSHandler {  
  4.     public Context context;  
  5.       
  6.     public JSHandler(Context c) {  
  7.         this.context = c;  
  8.     }  
  9.   
  10.     public void doSomething() {  
  11.         Log.d("JSHandler""doSomething@JSHandler");  
  12.         Toast.makeText(this.context, "doSomething@JSHandler", Toast.LENGTH_LONG).show();  
  13.     }  
  14. }  

addJavascriptInterface()方法的第一个参数就是要暴露给JavaScript的Class对象,第二个参数是可以调动该Class方法的JavaScript的全局变量。 

Js代码  收藏代码
  1. $(function() {  
  2.     Bridge.doSomething();  
  3. });  


但是addJavascriptInterface()方法存在安全隐患,在JavaScript中可以反射调用到Class的任意属性,比如以下代码能够取到Activity的package名。 
Js代码  收藏代码
  1. $(function() {    
  2.     var klass = Bridge.getClass();  
  3.     var field = klass.getDeclaredField('context');  
  4.     field.setAccessible(true);  
  5.     var context = field.get(Bridge);  
  6.     document.getElementById('res').innerHTML = context.getPackageName();  
  7. });  

 

Android 4.2 Jelly Bean以后版本,只有标示了@JavascriptInterface的方法JavaScript才能调到。 
Java代码  收藏代码
  1. webView.addJavascriptInterface(new MyCustomHander(this), "Bridge");  
  2.   
  3. class MyCustomHander {  
  4.     public Context context;  
  5.       
  6.     public MyCustomHander(Context c) {  
  7.         this.context = c;  
  8.     }  
  9.       
  10.     @JavascriptInterface  
  11.     public void doSomething() {  
  12.         Log.d("MyCustomHander""doSomething@MyCustomHander");  
  13.         Toast.makeText(this.context, "doSomething@MyCustomHander", Toast.LENGTH_LONG).show();  
  14.     }  
  15.       
  16.     public void doSomething2() {  
  17.         Log.d("MyCustomHander""doSomething2@MyCustomHander");  
  18.         Toast.makeText(this.context, "doSomething2@MyCustomHander", Toast.LENGTH_LONG).show();  
  19.     }  
  20. }  


Android 4.2以前版本看到的是:"doSomething2@MyCustomHander",而Android 4.2以后版本看到的是:"doSomething@MyCustomHander"。 
比如Android 4.1: 
 

(2)自定义URL 

Java代码  收藏代码
  1. webView.setWebViewClient(new WebViewClient() {  
  2.     @Override  
  3.     public boolean shouldOverrideUrlLoading(WebView view, String url) {  
  4.         if (url.startsWith("apicall://")) {  
  5.             Log.d("MyWebViewClient""doSomething@WebViewClient: " + url);  
  6.             Toast.makeText(getBaseContext(), "doSomething@WebViewClient: " + url, Toast.LENGTH_LONG).show();  
  7.             return true;  
  8.         }  
  9.         return false;  
  10.     }  
  11. });  


Js代码  收藏代码
  1. $(function() {  
  2.   window.location = 'apicall:////some_api_name/exec?a=1&b=2';  
  3. });  

 

(3)JsAlert 

Java代码  收藏代码
  1. webView.setWebChromeClient(new WebChromeClient() {  
  2.     @Override  
  3.     public boolean onJsAlert(WebView view, String url,  
  4.             String message, JsResult result) {  
  5.         Log.d("MyWebChromeClient""doSomething@WebChromeClient: " + message);  
  6.         Toast.makeText(getBaseContext(), "doSomething@WebChromeClient: " + message, Toast.LENGTH_LONG).show();  
  7.         // return super.onJsAlert(view, url, message, result);  
  8.         return true;  
  9.     }  
  10. });  


Js代码  收藏代码
  1. $(function() {  
  2.   alert("123");  
  3. });  

 

(4)搭建本地HTTP服务器 

NanoHttpd 是一个轻量级的可嵌入的HTTP服务器。 
Java代码  收藏代码
  1. public class APIHttpServer extends NanoHTTPD {  
  2.   
  3.     public APIHttpServer() {  
  4.         super(4000);  
  5.     }  
  6.   
  7.     @Override  
  8.     public Response serve(String uri, Method method,  
  9.             Map<String, String> headers, Map<String, String> params,  
  10.             Map<String, String> files) {  
  11.   
  12.         String data = "uri=" + uri + ", params=" + params;  
  13.         Log.d("APIHttpServer""doSomething@APIHttpServer: " + data);  
  14.   
  15.         return new NanoHTTPD.Response(Status.OK, "application/json""{msg:'nano'}");  
  16.     }  
  17. }  
  18.   
  19. APIHttpServer server = new APIHttpServer();  
  20. server.start();  


Js代码  收藏代码
  1. $(function() {  
  2.   $.getJSON("http://localhost:4000/some_api_name?a=1&b=2&c=3");  
  3. });  


AndroidManifest.xml 
Xml代码  收藏代码
  1. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>  
  2. <uses-permission android:name="android.permission.INTERNET"/>  


 


还有一种方法,通过URL的变更也能够实现,但是存在安全问题,基本不使用! 
Js代码  收藏代码
  1. window.location = 'http://cdv_exec/' + service + '#' + action + '#' + callbackId + '#' + argsJson;  

Java代码  收藏代码
  1. public class MyWebViewClient extends WebViewClient {  
  2.   public boolean shouldOverrideUrlLoading(WebView view, String url) {  
  3.     if (url.startsWith("http://cdv_exec/")) {  
  4.       handleExecUrl(url); // 截取参数处理  
  5.     }  
  6.   }  
  7. }  


参考: 
http://www.buildinsider.net/mobile/bookhtml5hybrid

相关文章推荐

Android JavascriptBridge 详解(二)

Android开发目前现状来说,开发者大部分时间花在UI的屏幕适配上,使用原生控件开发成本已不是那么的理想,鉴于很多项目保持和iOS一致的UI界面风格,至使移动UI开发成本花费更大的代价,因此目前结合...

Android Development: JavaScript Bridge Example – Fully Explained!

Copied from http://blog.objectgraph.com/index.php/2012/03/16/android-development-javascript-bridge...

在Android系统使用socket在Java层和native之间数据通信

Android是基于linux的系统,系统底层机制基本上是相同的,因为分本地代码和java代码,并且是java代码通过jni调用本地代码执行。 因为UDP报文发送是有局限的,局限就是当发送方...

React Native平台与Android本地模块之间的调用

原文链接http://blog.csdn.net/u011068702/article/details/49475167 有时候APP需要做出React Native平台没有的功能,你也许会...

Android之React Native平台与Android本地模块之间的调用

Native 模块(Android)          有时候APP需要做出React Native平台没有的功能,你也许会想用一些存在的java代码去解决问题,而不是用javascript脚本去去解...

Android关于JavaScript与Native方法相互调用

前段时间,阿里的去啊App 5.1.1发布了,这轮发布的热点就是Hybrid混合框架搞定了H5的“无缝秒出”。伴随着H5的发展,Native+HTML5的混合开发模式已经成为一种潮流,著名的框架比如F...

Android中WebView的JavaScript-native交互

一、Android中WebView的漏洞分析 最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能...

React-Native系列Android——Javascript文件加载过程分析

React-Native应用程序的内容是由Javascript语言开发的,而Android或者IOS手机系统只是一个容器和各类服务提供者。众所周知,Javascript是一门解释型脚本语言,对于浏览器...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)