Js与本地代码的交互的一些用法
来源:互联网 发布:程序员教程(第4版) 编辑:程序博客网 时间:2024/06/05 01:16
js和本地交互
最近项目要求用js和本地交互,所以就去看了下webview的一些api,发现只能满足一些简单的需求,而项目里面的需求是比较多的而且要用的功能也算有点复杂,所以想想去githup搜索了下,有大神已经把这些东西封装好了。基本能满足大部分需求了。接下来说下他的用法,只是用他的源码需要把WebViewJavascriptBridge.js这文件拷贝到你的assets资源文件目录下,这个类里面自己封装了一些用于消息处理的方法。看下他的项目结构在model里面就是一个user实体了,后面有用到,接着看MainActivity.java
package com.lyk.jsbridge;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.support.design.widget.FloatingActionButton;import android.support.design.widget.Snackbar;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.Toolbar;import android.util.Log;import android.view.View;import android.webkit.ValueCallback;import android.webkit.WebChromeClient;import android.widget.Toast;import com.github.lzyzsd.jsbridge.BridgeHandler;import com.github.lzyzsd.jsbridge.BridgeWebView;import com.github.lzyzsd.jsbridge.BridgeWebViewClient;import com.github.lzyzsd.jsbridge.CallBackFunction;import com.github.lzyzsd.jsbridge.DefaultHandler;import com.google.gson.Gson;import com.lyk.jsbridge.modle.User;public class MainActivity extends AppCompatActivity { private BridgeWebView mWebView; ValueCallback<Uri> mUploadMessage; int RESULT_CODE = 0; private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); mWebView = (BridgeWebView) findViewById(R.id.webView); initWebView(); } private void initWebView() { // 设置具体WebViewClient mWebView.setWebViewClient(new MyWebViewClient(mWebView)); // set HadlerCallBack mWebView.setDefaultHandler(new myHadlerCallBack()); // setWebChromeClient mWebView.setWebChromeClient(new WebChromeClient() { @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType, String capture) { this.openFileChooser(uploadMsg); } @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> uploadMsg, String AcceptType) { this.openFileChooser(uploadMsg); } public void openFileChooser(ValueCallback<Uri> uploadMsg) { mUploadMessage = uploadMsg; pickFile(); } }); mWebView.loadUrl("file:///android_asset/demo.html"); //必须和js函数名字一致,注册好具体执行回调函数,类似java实现类。 mWebView.registerHandler("submitFromWeb", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { String str = "这是html返回给java的数据:" + data; // 例如你可以对原始数据进行处理 str = str + ",Java经过处理后截取了一部分:" + str.substring(0, 5); Log.i(TAG, "handler = submitFromWeb, data from web = " + data); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); //回调返回给Js function.onCallBack(str + ",Java经过处理后截取了一部分:" + str.substring(0, 5)); } }); mWebView.registerHandler("functionOpen", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { Toast.makeText(MainActivity.this, "网页在打开你的下载文件预览", Toast.LENGTH_SHORT).show(); pickFile(); } }); //模拟用户信息 获取本地位置,用户名返回给html User user = new User(); user.setLocation("上海"); user.setName("Bruce"); // 回调 "functionInJs" mWebView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() { @Override public void onCallBack(String data) { Toast.makeText(MainActivity.this, "网页在获取你的位置,"+ data, Toast.LENGTH_SHORT).show(); } }); mWebView.send("hello"); } /** * 自定义的WebViewClient */ class MyWebViewClient extends BridgeWebViewClient { public MyWebViewClient(BridgeWebView webView) { super(webView); } } /** * 自定义回调 */ class myHadlerCallBack extends DefaultHandler { @Override public void handler(String data, CallBackFunction function) { if(function != null){ Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show(); } } } public void pickFile() { Intent chooserIntent = new Intent(Intent.ACTION_GET_CONTENT); chooserIntent.setType("image/*"); startActivityForResult(chooserIntent, RESULT_CODE); } @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == RESULT_CODE) { if (null == mUploadMessage) { return; } Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData(); mUploadMessage.onReceiveValue(result); mUploadMessage = null; } }}
- js里面的代码:
html><head> <meta content="text/html; charset=utf-8" http-equiv="content-type"> <title> js调用java </title></head><body><p> <xmp id="show"> </xmp></p><p> <xmp id="init"> </xmp></p><p> <input type="text" id="text1" value="用户名(username)"/></p><p> <input type="text" id="text2" value="password"/></p><p> <input type="button" id="enter" value="发消息给Native" onclick="testClick();" /></p><p> <input type="button" id="enter1" value="调用Native方法" onclick="testClick1();" /></p><p> <input type="button" id="enter2" value="显示源代码" onclick="testDiv();"/></p><p> <input type="file" id="open" value="打开文件" onclick="onOpen();"/></p></body><script> function onOpen() { var str1 = document.getElementById("text1").value; var str2 = document.getElementById("text2").value; var data = "name=" + str1 + ",pass=" + str2; //call native method window.WebViewJavascriptBridge.callHandler( 'functionOpen' , {'param': data } , function(responseData) { //document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData; } ); } function testDiv() { document.getElementById("show").innerHTML = document.getElementsByTagName("html")[0].innerHTML; } function testClick() { var str1 = document.getElementById("text1").value; var str2 = document.getElementById("text2").value; //发送消息给java本地代码 var data = {id: 1, content: "这是一个图片 <img src=\"a.png\"/> test\r\nhahaha"}; window.WebViewJavascriptBridge.send( data , function(responseData) { document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData } ); } function testClick1() { var str1 = document.getElementById("text1").value; var str2 = document.getElementById("text2").value; var data = "name=" + str1 + ",pass=" + str2; //call native method window.WebViewJavascriptBridge.callHandler( 'submitFromWeb' , {'param': data } , function(responseData) { document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData } ); } function bridgeLog(logContent) { document.getElementById("show").innerHTML = logContent; } function connectWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { callback(WebViewJavascriptBridge) } else { document.addEventListener( 'WebViewJavascriptBridgeReady' , function() { callback(WebViewJavascriptBridge) }, false ); } } // 第一连接时初始化bridage connectWebViewJavascriptBridge(function(bridge) { bridge.init(function(message, responseCallback) { console.log('JS got a message', message); var data = { 'Javascript Responds': '测试中文!' }; console.log('JS responding with', data); responseCallback(data); }); // 注册一个"functionInJs", bridge.registerHandler("functionInJs", function(data, responseCallback) { document.getElementById("show").innerHTML = ("data from Java: = " + data); var responseData = "Javascript Says 我要你的地址!"; // response层 responseCallback(responseData); }); }) bridge.init(function(message, responseCallback) { console.log('JS got a message', message); var data = { 'Javascript Responds': 'Wee!' }; console.log('JS responding with', data); responseCallback(data); });</script></html>
首先看下js里面的代码,可以看到有button,对应俩个点击事件onclick(),onclick1(); 再看下面的代码找到这个俩个方法的实现,
//第一个实现function testClick() { var str1 = document.getElementById("text1").value; var str2 = document.getElementById("text2").value; //发送消息给java本地代码 var data = {id: 1, content: "这是一个图片 <img src=\"a.png\"/> test\r\nhahaha"}; window.WebViewJavascriptBridge.send( data , function(responseData) { document.getElementById("show").innerHTML = "repsonseData from java, data = " + responseData } ); }//这里是第二个实现 function testClick1() { var str1 = document.getElementById("text1").value; var str2 = document.getElementById("text2").value; var data = "name=" + str1 + ",pass=" + str2; //call native method window.WebViewJavascriptBridge.callHandler( 'submitFromWeb' , {'param': data } , function(responseData) { document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData } ); }
可以看到俩个方法里面都有
//call native method
window.WebViewJavascriptBridge.callHandler(
‘submitFromWeb’之类的写法,这里就是开始调用本地的方法,注释里面写的很清楚,注意这里的单引号的字符串就是对应java中的别名,所以只要到java本地代码中去看看,找到这别名就知道他的调用了。go~go~go!
//必须和js函数名字一致,注册好具体执行回调函数,类似java实现类。 mWebView.registerHandler("submitFromWeb", new BridgeHandler() { @Override public void handler(String data, CallBackFunction function) { String str = "这是html返回给java的数据:" + data; // 例如你可以对原始数据进行处理 str = str + ",Java经过处理后截取了一部分:" + str.substring(0, 5); Log.i(TAG, "handler = submitFromWeb, data from web = " + data); Toast.makeText(MainActivity.this, str, Toast.LENGTH_SHORT).show(); //回调返回给Js function.onCallBack(str + ",Java经过处理后截取了一部分:" + str.substring(0, 5)); } });
找到了,上面的代码就是到这webview 标上’submitFromWeb’别名,注册一个回调,看注释,其中data是点击js中的button给我的数据,而就是通过这个类CallBackFunction 将本地java的数据回调给js的: function.onCallBack(str + “,Java经过处理后截取了一部分:” + str.substring(0, 5)); 一定要注意这里的别名一定要写的跟js中的一致,不然找不到的,关于原理,其实是他内部用了一个结合将这个别名和接口装载,然后js获取的时候会根据这别名找到对应的接口也就是这个BrigeHandler,然后回调里面的数据,要弄清楚里面的细节可以自己看源码,这个过程就是js调用本地的一种,再看看本地调用js的。
//模拟用户信息 获取本地位置,用户名返回给html User user = new User(); user.setLocation("上海"); user.setName("Bruce"); // 回调 "functionInJs" mWebView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() { @Override public void onCallBack(String data) { Toast.makeText(MainActivity.this, "网页在获取你的位置,"+ data, Toast.LENGTH_SHORT).show(); } }); mWebView.send("hello");
然后找到js中别名部分的代码:
// 注册一个"functionInJs", bridge.registerHandler("functionInJs", function(data, responseCallback) { document.getElementById("show").innerHTML = ("data from Java: = " + data); var responseData = "Javascript Says 我要你的地址!"; // response层 responseCallback(responseData); });
注释非常清楚,可以看的出来,本地java将一个data user数据传过去了,而js中通过responseCallback回调给本地的数据,这就是一个回调的过程,自己看注释,还是非常容易理解掌握的~!
好了,今天,就先到这里~大家有问题可以发我邮箱(593769469@qq.com)或者留言。
- Js与本地代码的交互的一些用法
- iOS webView与本地js的交互
- Android与Js交互的一些总结
- android 与js交互的一些坑
- JS与后台的交互一些笔记
- js与android代码的交互
- Android中js交互以及webview的一些用法
- Android-使用JsBridge来优化js与本地的交互
- WebView的JavaScript与本地代码三种交互方式
- WebView的JavaScript与本地代码三种交互方式
- WebView的JavaScript与本地代码三种交互方式
- WebView的JavaScript与本地代码三种交互方式
- 实现js与Qt程序的交互的一些方法
- 8 (phonegap源码分析)JS与本地代码交互(exec )
- JS与WebView交互存在的一些问题
- iOS-WKWebView特性以及与JS交互的一些事
- JS与WebView交互存在的一些问题
- Android JS与WebView交互存在的一些问题
- Ubuntu常用配置及技巧——14.04
- 新手随笔
- hadoop自定义分区函数
- Android 让WebView完美支持https双向认证(SSL)
- Linux多台机器配置ssh免登录
- Js与本地代码的交互的一些用法
- 【UE4】 第07讲 【MOBA制作日记】 实现自定义的行走控件
- Resources.FindObjectsOfTypeAll过滤掉预设体的方法
- table中删除多行中的td
- App后台开发运维和架构实践学习总结(4)——APP的注册和登录功能设计
- Puppet的安装部署
- cookie的用法
- 基于 Jenkins 快速搭建持续集成环境
- 有关Android ListView根据项数的大小自动改变高度问题