Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

WebView JS交互 addJavascriptInterface MD


目录

原生和 JS 交互

Demo

注意,如果在 java 与 Javascript 交互的时候出现如下错误:

Uncaught ReferenceError: <pre name="code" class="html">getDeviceID 

很可能是因为在 html 页面还没有加载完,就加载里面的 JS 方法,这样是找不到这个方法的。

解决方法为:把调用放到 onPageFinished() 里面

addJavascriptInterface

addJavascriptInterface

void addJavascriptInterface(Object object, String name)

参数:

  • Object object : the Java object to inject注入 into this WebView's JavaScript context. Null values are ignored.
  • String name : the name used to expose暴露、公开 the object in JavaScript

方法说明:

  • Injects the supplied Java object into this WebView.
  • The object is injected into the JavaScript context of the main frame, using the supplied name.
  • This allows the Java object's methods to be accessed from JavaScript.
  • For applications targeted to API level JELLY_BEAN_MR1 and above, only public methods that are annotated with JavascriptInterface can be accessed from JavaScript.
  • For applications targeted to API level JELLY_BEAN or below, all public methods (including the inherited继承的 ones) can be accessed, see the important security note安全注意事项 below for implications意义、含义.
  • Note that injected objects will not appear in JavaScript until the page is next (re)loaded. JavaScript should be enabled before injecting the object.

使用案例:

class JsObject {
@JavascriptInterface
public String toString() { return "injectedObject"; }
} webview.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new JsObject(), "injectedObject");
webView.loadData("", "text/html", null);
webView.loadUrl("javascript:alert(injectedObject.toString())");

IMPORTANT

  • This method can be used to allow JavaScript to control the host application.
  • This is a powerful feature, but also presents a security risk for apps targeting JELLY_BEAN or earlier.
  • Apps that target a version later than JELLY_BEAN are still vulnerable很容易受到攻击 if the app runs on a device running Android earlier than 4.2.
  • The most secure way to use this method is to target JELLY_BEAN_MR1 and to ensure the method is called only when running on Android 4.2 or later.
  • With these older versions, JavaScript could use reflection to access an injected object's public fields.
  • Use of this method in a WebView containing untrusted content could allow an attacker攻击者 to manipulate操纵 the host application in unintended非预期 ways, executing执行 Java code with the permissions of the host application.
  • Use extreme care格外小心 when using this method in a WebView which could contain untrusted content.

说明:

  • JavaScript interacts with交互 Java object on a private, background thread of this WebView. Care is therefore required to maintain保持 thread safety.
  • The Java object's fields are not accessible.
  • For applications targeted to API level LOLLIPOP and above, methods of injected Java objects are enumerable枚举 from JavaScript.

removeJavascriptInterface

void removeJavascriptInterface(String name)

String name : the name used to expose暴露 the object in JavaScript. This value must never be null.

Removes a previously injected Java object from this WebView.

Note that the removal will not be reflected in JavaScript until the page is next (re)loaded.

evaluateJavascript

void evaluateJavascript (String script, ValueCallback<String> resultCallback)

参数:

String script : the JavaScript to execute.

ValueCallback resultCallback :

  • A callback to be invoked when the script execution completes with the result of the execution (if any).

    当脚本执行完成时的回调,如果有执行结果的话会携带执行结果。
  • May be null if no notification of the result is required.

    如果不需要结果通知,可以为null。

说明:

  • Asynchronously evaluates JavaScript in the context of the currently displayed page.

    在当前显示页面的上下文中异步执行JavaScript。
  • If non-null, resultCallback will be invoked with any result returned from that execution.

    如果非空,resultCallback会被回调并携带调用后返回的结果。
  • This method must be called on the UI thread and the callback will be made on the UI thread.

    此方法必须在UI线程上调用,并且回调也是运行在UI线程上的。

Compatibility note 兼容性说明

  • Applications targeting N or later, JavaScript state from an empty WebView is no longer persisted across navigations like loadUrl(String).

    目标版本为N或更高的应用程序,空的WebView中的JavaScript状态不再继续像loadUrl那样在navigations中保留。
  • For example, global variables and functions defined before calling loadUrl(String) will not exist in the loaded page.

    例如,在调用loadUrl之前定义的全局变量和函数将不会存在于加载的页面中。
  • Applications should use addJavascriptInterface(Object, String) instead to persist JavaScript objects across navigations.

    应用程序应该使用 addJavascriptInterface 来跨navigations维护(持久化)JavaScript对象。

案例

原生代码

webview.addJavascriptInterface(new JSInterface(this, webview), JSInterface.JS_INTERFACE_NAME);
public class JSInterface {
public static final String JS_INTERFACE_NAME = "JSInterface";//JS调用类名
private Context mContext;
private WebView webView; public JSInterface(Context context, WebView webView) {
this.mContext = context;
this.webView = webView;
} @JavascriptInterface
public void hello(String content) {
Log.i("bqt", "JS 调用原生时是否发生在主线程:" + (Looper.myLooper() == Looper.getMainLooper()));//false
new Handler(Looper.getMainLooper()).post(() -> //WebView等UI操作必须在主线程中进行
Toast.makeText(mContext, "原生的hello方法被调用了:" + content, Toast.LENGTH_SHORT).show()); SystemClock.sleep(3000);//模拟耗时操作 String call = "javascript:javacalljs(" + System.currentTimeMillis() + ")";//格式很重要,大部分错误都是由于格式问题导致的
new Handler(Looper.getMainLooper()).post(() -> webView.loadUrl(call));//WebView等UI操作必须在主线程中进行
} @JavascriptInterface
public void hello2(String content) {
new Handler(Looper.getMainLooper()).post(() -> Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show()); SystemClock.sleep(3000);//模拟耗时操作 String call = "javascript:javacalljs2(" + System.currentTimeMillis() + ")";//JS此方法的返回值会通过onReceiveValue回调到原生
new Handler(Looper.getMainLooper()).post(() -> webView.evaluateJavascript(call, value -> {
Log.i("bqt", "ValueCallback 是否发生在主线程:" + (Looper.myLooper() == Looper.getMainLooper()));//true
Toast.makeText(mContext, "【onReceiveValue】" + value, Toast.LENGTH_SHORT).show();
}));
}
}

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <button onclick='jscalljava("包青天")'>点击后调用 JS 的 jscalljava 方法,在此方法中 JS 调用原生 JSInterface 类中的 hello 方法,原生 hello 方法执行完操作后回调 JS 中的 javacalljs 方法</button>
<button onclick='jscalljava2()'>演示原生调用 JS 方法后,JS 将执行完return的结果通过原生提供的 ValueCallback 对象的 onReceiveValue 方法回调给原生</button> </body> <script type="text/javascript">
function jscalljava(content){
console.log("【jscalljava】");
JSInterface.hello(content);
} function jscalljava2(){
console.log("【jscalljava2】");
var content="[\"包青天\",\"白乾涛\",\"bqt\"]";
JSInterface.hello2(content);
} function javacalljs(content){
console.log("【js中的javacalljs方法被调用了】content="+content);
} function javacalljs2(content){
console.log("【js中的javacalljs2方法被调用了】content="+content);
return 20094;
} </script>
</html>

2017-8-25

WebView JS交互 addJavascriptInterface MD的更多相关文章

  1. WebView JS交互 JSBridge 案例 原理 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. android webview js交互 第一节 (java和js交互)

    转载请注明出处         挺帅的移动开发专栏  http://blog.csdn.net/wangtingshuai/article/details/8631835        在androi ...

  3. Android WebView加载本地html并实现Java与JS交互

    最近做的一个项目中,用到自定义地图,将自定义地图转换成html页面,现在需要做的是如何将本地的html加载到android中,并可以实现交互. 相关讲解: 其实webview加载资源的速度并不慢,但是 ...

  4. Webview Android与js交互

    Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true Android(Java)与JavaScript(HTML) ...

  5. 安卓高级 WebView的使用到 js交互

    我们先来学习 怎么使用再到用js和安卓源生方法交互 WebView简单使用 此部分转载并做了补充 原博客 原因:比较简单不是很想在写,我只要写js交互部分 WebView可以使得网页轻松的内嵌到app ...

  6. webview与js交互

     对于android初学者应该都了解webView这个组件.之前我也是对其进行了一些简单的了解,但是在一个项目中不得不用webview的时候,发现了webview的强大之处,今天就分享一下使用we ...

  7. [android] WebView与Js交互

    获取WebView对象 调用WebView对象的getSettings()方法,获取WebSettings对象 调用WebSettings对象的setJavaScriptEnabled()方法,设置j ...

  8. webview与js交互(转)

    原文:http://www.cnblogs.com/vanezkw/archive/2012/07/02/2572799.html 对于android初学者应该都了解webView这个组件.之前我也是 ...

  9. Android应用开发 WebView与服务器端的Js交互

    最近公司再添加功能的时候,有一部分功能是用的html,在一个浏览器或webview中展示出html即可.当然在这里我们当然用webview控件喽 WebApp的好处: 在应用里嵌套web的好处有这么几 ...

随机推荐

  1. HTTP协议-MIME类型

    每一个 URL 都代表着一个资源对象,而当我们请求一个网页的时候,看似只请求了一个 URI(统一资源标识符),实际上这个网页可能包含多个 URI,例如图片资源的 URI 和视频资源的 URI 等.此时 ...

  2. 面向对象设计原则 里氏替换原则(Liskov Substitution Principle)

    里氏替换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一. 里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现. LSP是继承复用的基石,只 ...

  3. csdn 音乐 怎么拦截 提交后的程序 csdn 栏目 音乐 csdn 添加 音乐

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha csdn 栏目 音乐 csdn 添加 音乐 ======= <embed src= ...

  4. codevs 1086 栈 2003年NOIP全国联赛普及组

    题目描述 Description 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). ...

  5. BZOJ4276 : [ONTAK2015]Bajtman i Okrągły Robin

    建立线段树, S向每个叶子连边,容量1,费用0. 孩子向父亲连边,容量inf,费用0. 每个强盗向T连边,容量1,费用为c[i]. 对应区间内的点向每个强盗,容量1,费用0. 求最大费用流即可. #i ...

  6. springmvc学习总结(二) -- maven+springmvc+spring+mybatis+mysql详细搭建整合过程讲解

    @_@ 写在最前 之前分享过下面这几篇: mybatis学习笔记(五) -- maven+spring+mybatis从零开始搭建整合详细过程(上)(附demo和搭建过程遇到的问题解决方法) myba ...

  7. shell 常用命令语句

    查找并删除 sudo fing / -name '*fcitx*' | xargs sudo rm -rf find . -type d -name ‘.svn’ | xargs rm -rf fin ...

  8. windows pm2 开机启动

    npm install pm2-windows-startup -g; pm2-startup install; pm2 kill; pm2 start ecosystem.config.js --o ...

  9. oracle 树型结构数据的查询

    Oracle中start by prior子句用法 connect by 是结构化查询中用到的,其基本语法是: select ... from tablename start with 条件1 con ...

  10. PHP 服务端 和 APP 客户端 实现 RSA+AES 双向加密解密

    目的:服务端和移动端双向加密解密 共有七个文件 其中包括三个类文件 lib_aes.php aes对称加密解密类 server_rsa_crypt.php 服务端RSA公钥私钥非对称加密解密类 cli ...