`
rensanning
  • 浏览: 3548083 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:38136
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:607280
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:682277
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:89325
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:401825
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69685
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:91693
社区版块
存档分类
最新评论

Android中JavaScript和Native之间的Bridge

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

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

(1)addJavascriptInterface/@JavascriptInterface
Android的WebView类的标准接口。
webView.addJavascriptInterface(new JSHandler(this), "Bridge");

class JSHandler {
	public Context context;
	
	public JSHandler(Context c) {
		this.context = c;
	}

	public void doSomething() {
		Log.d("JSHandler", "doSomething@JSHandler");
		Toast.makeText(this.context, "doSomething@JSHandler", Toast.LENGTH_LONG).show();
	}
}

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

$(function() {
	Bridge.doSomething();
});


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



Android 4.2 Jelly Bean以后版本,只有标示了@JavascriptInterface的方法JavaScript才能调到。
webView.addJavascriptInterface(new MyCustomHander(this), "Bridge");

class MyCustomHander {
	public Context context;
	
	public MyCustomHander(Context c) {
		this.context = c;
	}
	
	@JavascriptInterface
	public void doSomething() {
		Log.d("MyCustomHander", "doSomething@MyCustomHander");
		Toast.makeText(this.context, "doSomething@MyCustomHander", Toast.LENGTH_LONG).show();
	}
	
	public void doSomething2() {
		Log.d("MyCustomHander", "doSomething2@MyCustomHander");
		Toast.makeText(this.context, "doSomething2@MyCustomHander", Toast.LENGTH_LONG).show();
	}
}


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


(2)自定义URL

webView.setWebViewClient(new WebViewClient() {
	@Override
	public boolean shouldOverrideUrlLoading(WebView view, String url) {
		if (url.startsWith("apicall://")) {
			Log.d("MyWebViewClient", "doSomething@WebViewClient: " + url);
			Toast.makeText(getBaseContext(), "doSomething@WebViewClient: " + url, Toast.LENGTH_LONG).show();
			return true;
		}
		return false;
	}
});


$(function() {
  window.location = 'apicall:////some_api_name/exec?a=1&b=2';
});



(3)JsAlert

webView.setWebChromeClient(new WebChromeClient() {
	@Override
	public boolean onJsAlert(WebView view, String url,
			String message, JsResult result) {
		Log.d("MyWebChromeClient", "doSomething@WebChromeClient: " + message);
		Toast.makeText(getBaseContext(), "doSomething@WebChromeClient: " + message, Toast.LENGTH_LONG).show();
		// return super.onJsAlert(view, url, message, result);
		return true;
	}
});


$(function() {
  alert("123");
});



(4)搭建本地HTTP服务器

NanoHttpd 是一个轻量级的可嵌入的HTTP服务器。
public class APIHttpServer extends NanoHTTPD {

	public APIHttpServer() {
		super(4000);
	}

	@Override
	public Response serve(String uri, Method method,
			Map<String, String> headers, Map<String, String> params,
			Map<String, String> files) {

		String data = "uri=" + uri + ", params=" + params;
		Log.d("APIHttpServer", "doSomething@APIHttpServer: " + data);

		return new NanoHTTPD.Response(Status.OK, "application/json", "{msg:'nano'}");
	}
}

APIHttpServer server = new APIHttpServer();
server.start();


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


AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>





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

public class MyWebViewClient extends WebViewClient {
  public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith("http://cdv_exec/")) {
      handleExecUrl(url); // 截取参数处理
    }
  }
}


参考:
http://www.buildinsider.net/mobile/bookhtml5hybrid
  • 大小: 49.3 KB
  • 大小: 21.9 KB
  • 大小: 18.8 KB
  • 大小: 19.9 KB
  • 大小: 13.3 KB
  • 大小: 11 KB
  • 大小: 3 KB
分享到:
评论

相关推荐

    Android和ReactNative混合开发Demo

    本教程通过"Android和React Native混合开发Demo",将详细介绍如何在Android应用中集成React Native,实现原生代码与React Native组件之间的双向通信。 首先,Android原生加载RN页面是混合开发的基础。这涉及到在...

    Android项目中集成react native页面

    在Android项目中集成React Native页面是一项常见的开发任务,它允许开发者利用JavaScript和React库来创建原生移动应用的UI部分,同时保持与Android代码的交互。以下是对这个过程的详细解释: 1. **React Native简介...

    ReactNative与Android原生简单交互

    ReactNative是一种由Facebook开发的开源框架,它允许开发者使用JavaScript和React库来构建原生的移动应用程序,同时兼容iOS和Android平台。ReactNative的核心理念是“Learn once, write anywhere”,这意味着开发者...

    reactnativeeventbridge在ReactNative和原生之间发送和接收事件

    React Native Event Bridge是React Native框架中的一个重要组成部分,它允许JavaScript(JS)代码与原生iOS或Android代码之间进行通信,从而实现更高效、更复杂的交互。这个技术在混合移动开发中扮演着关键角色,...

    Android与javascript的双向交互

    在移动应用开发中,Android平台和JavaScript的交互是常见的需求,尤其在混合开发模式下,如Cordova或React Native。本文将深入探讨如何实现Android与JavaScript的双向交互,以达到充分利用两者的优势,提高开发效率...

    Android React-Native通信数据模型分析

    通信数据模型在React-Native架构中扮演着至关重要的角色,因为它决定了JavaScript与原生平台(如Java for Android)之间如何高效、安全地交换数据。本文将深入探讨Android环境下React-Native的通信数据模型。 首先...

    ReactNative用javascript开发移动应用.中文完整版.pdf

    在React Native中,JavaScript和Native代码之间通过Bridge通信,这是一个异步过程,提高了应用的性能。开发者可以使用JavaScript处理业务逻辑和数据管理,而将视觉渲染和与硬件交互的任务留给原生模块。这使得React ...

    Android原生项目集成最新版本ReactNative

    在Android原生项目中集成最新版本的React Native是一项常见的任务,尤其对于希望利用React Native的JavaScript开发优势同时保持原生性能的应用来说。本教程将详细指导你如何将React Native逐步集成到你的Android应用...

    Android-为了修复ReactNative的WebView组件在安卓端不支持文件上传而包装的一个Webview组件

    4. **JavaScript Bridge**:React Native的JavaScript和Java/Kotlin之间的通信是通过JavaScript Bridge实现的。在这个场景下,桥接机制允许自定义的Android模块向JavaScript发送数据(如选中的文件路径),从而让...

    ReactNative调原生Android代码

    React Native 是一个由Facebook开发的开源框架,它允许开发者使用JavaScript和React库来构建原生的iOS和Android应用程序。在某些场景下,尽管React Native提供了丰富的组件和功能,但为了实现特定的设备交互、优化...

    Android-在ReactNative应用程序后台运行一个单独的Node.js进程

    React Native是一种使用JavaScript(通常配合TypeScript)编写原生移动应用的框架,它通过JavaScript Bridge与Android和iOS平台进行通信。但是,JavaScript环境并不支持长时间在后台运行的任务,因为当用户离开应用...

    Android-react-native支付宝手机支付模块

    在移动应用开发领域,React Native 是一个非常流行的框架,它允许开发者使用JavaScript来构建原生的iOS和Android应用程序。在Android应用中集成支付宝支付功能,是很多开发者在处理电子商务或服务付费场景时需要解决...

    reactnative调用android原生模块Toast学习笔记

    在这个过程中,我们通常会创建一个Java或Kotlin类来封装原生API,然后通过React Native的Bridge机制暴露给JavaScript。 1. **创建Android原生模块** 要创建一个原生模块,首先在Android工程的`java`目录下创建一个...

    android或者IOS使用hybrid实现native和h5交互

    - **WebViewBridge**:WebViewBridge是Android中用于通信的关键组件,它通常由两部分组成:JavaScript接口和Java接口。JavaScript接口暴露给H5,Java接口则在原生端实现具体功能。 - **调用方向**: - **H5调用...

    android js bridge

    综上所述,Android JS Bridge是Android开发中的一个重要工具,它使得Java和JavaScript的交互变得更加简单和高效,为混合应用开发提供了可能。通过合理的设计和实现,我们可以充分利用这一特性来提高应用的灵活性和可...

    实例详解Android Webview拦截ajax请求

    如果可以,那就需要一种在 JavaScript 和 Native 之间通信的桥梁(JavaScript Bridge),通过它,JavaScript 将请求信息传递给 Native,Native 完成真正的请求后再将结果数据传递给 JavaScript。 思路虽然简单,但...

    androidApp横竖屏接口_religiousryg_reactnative_android_

    首先,ReactNative(RN)是一个由Facebook开发的开源JavaScript框架,它允许开发者使用JavaScript和React编写原生移动应用。RN通过桥接机制与原生平台进行交互,提供了丰富的API和组件库。在处理横竖屏切换这样的...

    一个用于ReactNative框架的纯JavaScript的杂志listview

    2. **JavaScript与Native交互**:React Native允许JavaScript与原生平台之间进行通信,通过`Native Modules`和`Bridge`机制实现。理解这一过程对于定制或扩展组件至关重要。 3. **ListView组件**:深入理解ListView...

Global site tag (gtag.js) - Google Analytics