版权声明:会开花的树 https://blog.csdn.net/qiaoshi96_bk/article/details/81369067
前言
项目中遇到要通过原生去分享h5页面的内容,但是产品经理的需求比较奇葩:
如果当前页面存在分享方法则去调取页面分享的方法,如果没有则取页面的第一张图片为分享图片,description为分享内容
拿到需求的时候心里一愣一愣的,卧槽还有这种操作但是产品大人在上还是想办法去实现了。
思路
我当时想,通过WebView我们可以拿到页面的title和URL但是产品的需求时页面有分享方法得自己获取,这个肯定涉及到和js交互了,那去哪页面第一张图片呢?第一反应是去抓包,后来想想不现实,这样无论是性能还是抓到数据去处理数据都不是上上策。后来想一想,js通常是可以控制h5逻辑的,比如点击事件等,那么如果我在h5页面植入一段js代码,然后找一个触发点去执行他是不是就可以拿到我想要的东西呢?事实证明多想一想是有用滴:
js交互
我们原生如何拿到js的方法呢?
这里不去多说细节:
settings.setJavaScriptEnabled(true);// 如果访问的页面中有Javascript,则webview必须设置支持Javascript。
这个是必须有的。然后我们可以在
mWebView.setWebViewClient(new WebViewClient()
这个方法中去重写
public void onPageFinished(WebView view, String url) {//通过view.getTitle方法拿到标题
// 添加js接口,实现往浏览器添加进一个js对象,名称为:WebViewJavascriptBridge
webview.addJavascriptInterface(new CTOJavaScriptCallback(context), "WebViewJavascriptBridge");
然后通过注解:
@JavascriptInterface
public void getShareInfo(String result) {
results = result;
}
这样就可以拿到自己想要的方法,前提就是
WebViewJavascriptBridge 以及 getShareInfo是你和js那边约定好的方法
执行h5页面方法
如何去获取h5页面我想要的值呢?
其实只要通过
//无图片时获取页面第一张图片作为分享图片
mWebView.loadUrl("javascript:(function(){" +
"var objs = document.getElementsByTagName(\"img\"); " +
" WebViewJavascriptBridge.Image(objs[0].src); " +
"})()");
//获取描述
mWebView.loadUrl("javascript:(function(){" +
"var str = document.getElementsByTagName(\"meta\")[\"description\"].getAttribute(\"content\");" +
"WebViewJavascriptBridge.Javavalue(str);" +
"})()");
在onPageFinished加载这连段js并且通过onPageFinished条件去触发这样我们就可以拿到返回值:
//获取描述
@JavascriptInterface
public void Javavalue(String description) {
WebviewActivity.getHtmlDesc(description);
}
//获取第一张图片
@JavascriptInterface
public static void Image(String image) {
WebviewActivity. getImageView(image);
}
通过这种方式,但是要注意的是:Java是通过String的样式去加载js的这里要去注意我们拼接的js要转义一下.
WebViewJavascriptBridge:是js的一个第三方库具体可以看:WebViewJavascriptBridge详解