WebView JS交互 addJavascriptInterface MD
| Markdown版本笔记 | 我的GitHub首页 | 我的博客 | 我的微信 | 我的邮箱 |
|---|---|---|---|---|
| MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
WebView JS交互 addJavascriptInterface MD
目录
原生和 JS 交互
注意,如果在 java 与 Javascript 交互的时候出现如下错误:
Uncaught ReferenceError: <pre name="code" class="html">getDeviceID
很可能是因为在 html 页面还没有加载完,就加载里面的 JS 方法,这样是找不到这个方法的。
解决方法为:把调用放到 onPageFinished() 里面。
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
JavascriptInterfacecan 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
reflectionto access an injected object'spublic 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 threadof 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的更多相关文章
- WebView JS交互 JSBridge 案例 原理 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- android webview js交互 第一节 (java和js交互)
转载请注明出处 挺帅的移动开发专栏 http://blog.csdn.net/wangtingshuai/article/details/8631835 在androi ...
- Android WebView加载本地html并实现Java与JS交互
最近做的一个项目中,用到自定义地图,将自定义地图转换成html页面,现在需要做的是如何将本地的html加载到android中,并可以实现交互. 相关讲解: 其实webview加载资源的速度并不慢,但是 ...
- Webview Android与js交互
Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true Android(Java)与JavaScript(HTML) ...
- 安卓高级 WebView的使用到 js交互
我们先来学习 怎么使用再到用js和安卓源生方法交互 WebView简单使用 此部分转载并做了补充 原博客 原因:比较简单不是很想在写,我只要写js交互部分 WebView可以使得网页轻松的内嵌到app ...
- webview与js交互
对于android初学者应该都了解webView这个组件.之前我也是对其进行了一些简单的了解,但是在一个项目中不得不用webview的时候,发现了webview的强大之处,今天就分享一下使用we ...
- [android] WebView与Js交互
获取WebView对象 调用WebView对象的getSettings()方法,获取WebSettings对象 调用WebSettings对象的setJavaScriptEnabled()方法,设置j ...
- webview与js交互(转)
原文:http://www.cnblogs.com/vanezkw/archive/2012/07/02/2572799.html 对于android初学者应该都了解webView这个组件.之前我也是 ...
- Android应用开发 WebView与服务器端的Js交互
最近公司再添加功能的时候,有一部分功能是用的html,在一个浏览器或webview中展示出html即可.当然在这里我们当然用webview控件喽 WebApp的好处: 在应用里嵌套web的好处有这么几 ...
随机推荐
- hdu 4562 dp ***
题意:给出一个点p(X,Y)以及若干圆.从中选出尽可能多的圆满足:圆能且只能包含p或者原点中的一个(不能在圆上):圆之间不能相交或者相切. 链接:点我 用dp求满足条件包含一个点圆的最多数目,然后两个 ...
- Xtreme8.0 - Sum it up 水题
Sum it up 题目连接: https://www.hackerrank.com/contests/ieeextreme-challenges/challenges/sum-it-up Descr ...
- ROS知识(20)----SLAM资源集合
1.各种最新开源的SLAM a.OpenSLAM.这里收集了各种最新的开源SLAM资料,包含了比如: ORB_SLAM, ORB_SLAM2, hector_slam,ethzasl_ptam,g2o ...
- .Net中常用的重要的第三方组件
RSS.NET.dll RSS.NET是一款操作RSS feeds的开源.NET类库.它为解析和编写RSS feeds提供了一个可重用的对象模型.它完全兼容RSS 0.90, 0.91, 0.92, ...
- CAS服务器配置
参考文献: http://sucre.blog.51cto.com/1084905/683624 1.安装部署CAS Server 从官网下载CAS Server,今天发现CAS Server的官网居 ...
- jquery-chosen设置默认值
<span style="font-size:18px;"> <select id="select1" class="select1 ...
- 正确识别希捷Backup Plus新睿品1TB正品,杜绝奸商猖獗
刚刚在百度希捷贴吧发了此贴, 马上被删除, 无奈只能发于个人博客, 望看到的朋友能转载到"合适"位置,让更多的朋友看到. 避免上当. 最近准备买个移动硬盘备份电脑资料,看上了睿品 ...
- hdu 2546 饭卡(背包)
设饭卡余额为total 此题经分析 可以得出:要求选出一些饭菜 时消费量尽量接近total-5元 然后再买一个饭菜 以达到透支... 可以证明 最后买的那个饭菜是饭菜中价值最大的. 证明 设a1 ...
- 通过进程ID获取基地址
下面代码是通过进程ID来获取进程的基地址,创建一个进程快照后,读取进程模块,一般情况下第一个模块就是进程的基地址,下面的程序通过模块的字符串匹配来找到基地址.通过MODULEENTRY32来读取,下面 ...
- Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(2) 自己封装的Calendar接口
本章主要是收藏一些常用的类和接口,包括:万年历(农历.阳历节日.阴历节日).自定义的Calendar接口. 万年历 源码如下(ChineseCalendar.java): package com.vi ...