Giter Club home page Giter Club logo

androidjsinterface's Introduction

AndroidJSInterface

此项目,主要演示Android的WebView视图中,Native Call JavaScript、以及JavaScript Call Native的几种方式。


写在前面: Hybrid不可避免使用Native和JS交互,本文主要总结一下Android和JavaScript交互的解决方方。

[TOC]

A、Native调用JavaScript

方案一:调用loadUrl执行一段js
mWebView.loadUrl("javascript:alert('hello world')");
方案二:调用evaluateJavascript异步执行一段js
String jsString = "sum(a, b)";
mWebView.evaluateJavascript(js, new ValueCallback<String>() {
  @Override
  public void onReceiveValue(String s) {
    // 这里可以处理被调用js方法的return
  }
});
方案三:引用JsBridge框架
  • Web首先初始化WebViewJavascriptBridge,注册事件监听。
  • Web然后初始化接收函数回调,分为默认接收指定接收,responseCallback回调给Native信息
  • Native 调用Webview.send()WebView.callHandler()
//注册事件监听,初始化
function setupWebViewJavascriptBridge(callback) {
	if (window.WebViewJavascriptBridge) {
		callback(WebViewJavascriptBridge)
	} else {
		document.addEventListener(
                'WebViewJavascriptBridgeReady',
                function() {
                    callback(WebViewJavascriptBridge)
                },
                false
        );
    }
}

//回调函数,接收java发送来的数据
setupWebViewJavascriptBridge(function(bridge) {
   //默认接收
	bridge.init(function(message, responseCallback) {
		// 处理接收到消息
	});

	//指定接收,
	bridge.registerHandler("JSFUCN", function(data, responseCallback) {
		// 处理接收到消息
	});
})
    // 默认接收
    private void callJavaScriptDefaut() {
        mWebView.send("发送数据给js默认接收, new CallBackFunction() {
            @Override
            public void onCallBack(String data) { //处理js回传的数据
               
        });
    }
    // 指定接收
    private void callJavaScriptSpec() {
   

        mWebView.callHandler("JSFUCN", "发送数据给js指定接收", new CallBackFunction() {
            @Override
            public void onCallBack(String data) { //处理js回传的数据
               
            }
        });
    }

利用 webview调用js需要注意一下几点

  • WebSettings设置支持javascript
// 设置在类之前
@SuppressLint("SetJavaScriptEnabled") 
mWebView.getSettings().setJavaScriptEnabled(true);
  • 在运行Js脚本前,要有document对象,至少得load一个空白页
webView.loadData("","text/html","UTF-8");
  • 如果还是不行的话,就应该是因为第一个还没执行完呢 - 从界面按钮调用 - 延时调用 - 在onPageFinished中调用
webView.loadData(“”,"text/html","UTF-8");
webView.loadUrl("javascript:alert('hello')");
  • 必须实现WebChromeClient、WebViewClient
webView.setWebViewClient(new WebViewClient());
webView.setWebChromeClient(new WebChromeClient());
  • 使用JSBridge不用实现WebViewClient

B、JavaScript调用Native

方案一:拦截跳转
  • WebViewClient重载shouldOverrideUrlLoading 拦截URL

Web代码

function openMyBlogNewTarget() {
    window.open('https://www.jianshu.com/u/263c210b047c')
}

function openMyBlog() {
    window.location.href = 'https://www.jianshu.com/u/263c210b047c'
}
<a href="http://www.baidu.com" title="baidu" target="_blank">新标签页打开百度</a>
<a href="http://www.baidu.com" title="baidu" >当前页打开百度</a>

<button onclick='openMyBlogNewTarget()'>新标签打开我的博客</button>
<button onclick="openMyBlog()">打开我的博客</button>

Android代码

private class MYWebViewClient extends  WebViewClient {
	@Override
	public void onPageStarted(WebView view, String url, Bitmap favicon) {
		super.onPageStarted(view, url, favicon);
	}
	
	// 新方法 API21以后
	@Override
	public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
		super.shouldOverrideUrlLoading(view, request);
		
		// 拦截Request
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
			Log.d(TAG, "shouldOverrideUrlLoading: " + request.getUrl().toString());
       }
		return true;
	}
        
   // 旧方法 兼容API21之前
	@Override
	public boolean shouldOverrideUrlLoading(WebView view, String url) {
		super.shouldOverrideUrlLoading(view, url);
		// 拦截url
		Log.d(TAG, "shouldOverrideUrlLoading: " + url);
		return true;
	}
}
方案二:JSInterface
  • JS中使用window.objects.function语法调用Native,其中objects与Native中一直。
  • Native中定义Class,以及被调用的func用 public、@JavascriptInterface修饰。
  • Native中addJavascriptInterface(obj, name)
function callNative() {
	var amount = 123.5;
	var orderno = "FG1afsdakewqr";
	window.mobileApp.toPay(amount, orderno);
}
<button onclick="window.mobileApp.sendMessage('特斯拉 Model 3')">获取商品名</button>
<button onclick="callNative()">支付按钮</button>
mWebView.addJavascriptInterface(new JsInterface(tv), "mobileApp");


private class JsInterface {

	private TextView showText;
	
	public JsInterface(TextView tv) {
		showText = tv;
	}

	@JavascriptInterface
	public void sendMessage(String msg) {
		Log.d(TAG, "sendMessage: " + msg);

	}
        
   @JavascriptInterface
	public void toPay(float amount, String oderno) {
		Log.d(TAG, "sendMessage: " + amount);
    }
}
方案三:引用JsBridge框架
  • JS中调用window.WebViewJavascriptBridge.send 或者 window.WebViewJavascriptBridge.callHandler 向Native发消息
  • Native中注册指定接收WebView.registerHandler或者注册默认接收WebView.setDefaultHandler
//js传递数据给java
function jsCallNativeDefault() {
	window.WebViewJavascriptBridge.send({ 'param': "str1" },	function(responseData) { //处理java回传的数据

	});
}

function jsCallNativeSpec() {
	window.WebViewJavascriptBridge.callHandler(
	'Spec' //指定接收参数 submitFromWeb与java一致
	,'指定接收'
	,function(responseData) { //处理java回传的数据
	
	 });
}
mWebView.registerHandler("Spec", new BridgeHandler() {
	@Override
	public void handler(String data, CallBackFunction function) {
		Log.i("", "handler = submitFromWeb, data from web = " + data);
		function.onCallBack("submitFromWeb exe, response data 中文 from Java");
			showTextView.setText("指定接收:" + data);
		}
});

mWebView.setDefaultHandler(new DefaultHandler() {
	@Override
	public void handler(String data, CallBackFunction function) {
		Log.i("", "handler = submitFromWeb, data from web = " + data);
		function.onCallBack("submitFromWeb exe, response data 中文 from Java");
			showTextView.setText("默认接收:" + data);
		}
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.