Android中WebView的相关使用
近期做的项目中,遇到个非常棘手的问题:
客户给我的数据是有限制的,因此,在返回某条详细页面内容的时候,他仅仅能给我一个html片段,里面包括
文字,图片以及附件的下载地址。假设网页模版规范的爱比較好说,可是他给我的数据中,不确定的因素非常多:
比方 可能没有图片,图片和文字穿插在一起,最为重要的是html便签他的嵌套层次和标签个数都是不确定的。
假设我採用解析html提取内容出来的话,预计就掉进坑里了.......
但实际情况中,打算server先将客户代码的标签属性删除,仅仅剩骨头,但结果还是不尽人意,由于将全部原本的标签属性删除后,显示还是会有问题........。。。
因此,我看了一下网易新闻等感觉都是採用webview进行展示的,关键是怎样封装并处理好数据了。
学走路,还是从模仿開始。这里借鉴了大牛们的博客,经验,再次一并谢过:
http://blog.csdn.net/zi413293813/article/details/18144055
http://blog.csdn.net/kavensu/article/details/7931480
http://blog.csdn.net/wangtingshuai/article/details/8635787
http://blog.csdn.net/chenshijun0101/article/details/7045394
我的需求:下载图片;下载附件、
採用思路:将内容用html展示,而且实现java和js的交互,响应用户点击图片的动作。
这里我写了一个demo,依照上面别人的样例简单封装了一下,当然,这里仅仅是提供一种思路,详细怎么封装怎么去实现更好好还是的要详细问题详细分析了。
别忘了:加入写文件权限和网络权限
demo使用測试页面:http://www.cnbeta.com/articles/292267.htm
这里,由于他的内容太多,所以我直接去了主要内容部分,也就是有我文字和图片混搭的部分。
接口:主要用于回调,当然为了扩展的话,还能够加入很多其它方法。
package com.example.androidwebviewdemo; /**
* <p>
* </p>
* 下午8:04:06
*
* @auther xiangxm
*/
public interface IOnWebViewCallBack {
/**
* <p>
* 页面载入进度
* </p>
*
* @param progress
* void
*/
void onProgressChanged(int progress);
}
设置webview控件的相关属性:
private void initView() { progressbar = (ProgressBar) findViewById(R.id.progressbar);
progressbar.setVisibility(View.INVISIBLE);
mWebView = (WebView) findViewById(R.id.webview_ui);
WebSettings settings = mWebView.getSettings();
// 设置webview的相关属性
settings.setJavaScriptEnabled(true);// 同意运行js代码
settings.setBlockNetworkImage(true);
settings.setSupportZoom(false);// 不支持缩放
settings.setBuiltInZoomControls(false);// 内置缩放
settings.setPluginsEnabled(true);
settings.setDefaultTextEncodingName("UTF-8");// 设置默认编码
mWebView.getSettings()
.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);// 禁止因为内容过宽,导致横屏滚动。
mWebView.addJavascriptInterface(new JavaScriptInterface(),
HtmlParser.Js2JavaInterfaceName); HtmlParser htmlParser = new HtmlParser(mWebView,
"http://www.cnbeta.com/articles/292267.htm", this, this);
htmlParser.execute();
}
HtmlParser:依据别人的代码改变的,我主要把其它的操作都放进来了。感觉这样做会牵扯的太多了,不好扩展,但这里不过个demo而已。
直接上代码:HtmlParser
package com.example.androidwebviewdemo; import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient; /**
* <p>
* html处理的相关类:给图片加入onClick属性。,过滤a标签,加入属性等。、
* </p>
* 下午6:40:37
*
* @auther xiangxm
*/
public class HtmlParser extends AsyncTask<Void, Void, String> { public static String Js2JavaInterfaceName = "JsUseJava";
private WebView mWebView;
/** 网页地址 **/
private String htmlUrl = "";
private Context mContext;
/** 存储img标签图片地址。 **/
private List<String> imageUrlList = new ArrayList<String>(); public List<String> getImagerUrlList() {
return imageUrlList;
} public HtmlParser(WebView wevView, String url, Context context,
IOnWebViewCallBack onWebViewCallBack) {
this.mWebView = wevView;
htmlUrl = url;
mContext = context;
this.onWebViewCallBack = onWebViewCallBack;
configWebView();
} /**
* <p>
* 配置WebView的相关信息
* </p>
* void
*/
private void configWebView() { //
mWebView.setWebViewClient(new MyWebClient());
mWebView.setWebChromeClient(new MyWebChrome()); } class MyWebClient extends WebViewClient { @Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
} @Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url); mWebView.getSettings().setBlockNetworkImage(false);// 关闭图片堵塞
// 页面载入完毕之后,更换图片显示,异步更换图片显示。
DownloadWebImgTask downloadTask = new DownloadWebImgTask(mWebView);
List<String> urlStrs = imageUrlList;
String urlStrArray[] = new String[urlStrs.size() + 1];
urlStrs.toArray(urlStrArray);
downloadTask.execute(urlStrArray);
if (null != onWebViewCallBack) { onWebViewCallBack.onProgressChanged(View.INVISIBLE);
}
} @Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { // 当连接被点击的时候希望覆盖而不是打开新的窗体
// view.loadUrl(url);
return true;
} } class MyWebChrome extends WebChromeClient { @Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
// 载入的时候显示运行进度能够在这里加入
if (null != onWebViewCallBack) {
// 载入显示运行进度的时候
// onWebViewCallBack.onProgressChanged(newProgress);
}
}
} private IOnWebViewCallBack onWebViewCallBack; public void setOnWebViewCallBack(IOnWebViewCallBack onWebViewCallBack) {
this.onWebViewCallBack = onWebViewCallBack;
} /**
* <p>
* 注入js代码,加入Onclick事件
* </p>
*
* @param doc
* void
*/
public void handleImageClickEvent(Document doc) { Elements es = doc.getElementsByTag("img"); for (Element e : es) {
String imgUrl = e.attr("src");
imageUrlList.add(imgUrl);
String imgName;
File file = new File(imgUrl);
imgName = file.getName();
if (imgName.endsWith(".gif")) {
e.remove();
} else { String filePath = "file:///mnt/sdcard/test/" + imgName;
e.attr("src", "file:///android_asset/ic_launcher.png");
e.attr("src_link", filePath);
e.attr("ori_link", imgUrl);
String str = "window." + Js2JavaInterfaceName + ".setImgSrc('"
+ filePath + "')";
e.attr("onclick", str); }
}
} /**
* <p>
* 与java交互 将a超链接标签,点击后提供下载
* </p>
*
* @param doc
* void
*/
private void handleHyperlinks(Document doc) {
Elements hrefs = doc.getElementsByTag("a");
for (Element href : hrefs) {
String str = "window." + Js2JavaInterfaceName + ".onClick_Tag_A('"
+ href.attr("href") + "')"; href.attr("onclick", str);
}
} @Override
protected String doInBackground(Void... params) { if (null != onWebViewCallBack) { onWebViewCallBack.onProgressChanged(View.VISIBLE);
}
Document doc = null;
imageUrlList.clear(); try {
doc = Jsoup.parse(new URL(htmlUrl), 15000);
} catch (MalformedURLException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} if (doc == null)
return null; Elements es = doc.select("script");
if (es != null) {
es.remove();
}
Document docNew = Jsoup.parse(doc.getElementsByClass("article_content")
.html());
handleImageClickEvent(docNew);
handleHyperlinks(docNew);
Log.i("-------->html内容", docNew.toString());
return docNew.toString(); } @Override
protected void onPostExecute(String result) {
super.onPostExecute(result); mWebView.loadDataWithBaseURL(null, result, "text/html", "utf-8", null);// 这样展示能够有效放置中文乱码
super.onPostExecute(result); } }
当点击了图片之后:通常情况下会跳转到浏览器新页面覆盖。这里实现需求是,点击图片不跳转,直接将WebViewClient的shouldOverrideUrlLoading return true;将事件消费掉就OK。
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { // 当连接被点击的时候希望覆盖而不是打开新的窗体
// view.loadUrl(url);
return true;
}
执行效果图:
demo显示内容的时候有点慢。
Android中WebView的相关使用的更多相关文章
- Android中WebView的JavaScript代码和本地代码交互的三种方式
一.Android中WebView的漏洞分析最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视 ...
- Android中webView和网页的交互
Android中webView和网页的交互 Android中webView跟网页的交互式通过JavaScript进行的.具体步骤: 1.创建JavaScript,在点击的时候调用JavaScript ...
- Android 中Webview 自适应屏幕
随笔 - 478 文章 - 3 评论 - 113 Android 中Webview 自适应屏幕 webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomCon ...
- android 中webview的屏幕适配问题
两行代码解决WebView的屏幕适配问题 一个简单的方法,让网页快速适应手机屏幕,代码如下 1 2 WebSettings webSettings= webView.getSettings(); we ...
- Android中webview和js之间的交互(转)
http://www.cnblogs.com/leizhenzi/archive/2011/06/29/2093636.html 1.android中利用webview调用网页上的js代码. Andr ...
- Android中Webview使用自定义的javascript进行回调
先说为什么需要讨论这个问题. 现在很多的手机应用,都可能会直接嵌入一个web页面.这样做的好处:一个是功能更新方便,维护起来容易,只需要维护服务器的页面即可,不需要更新客户端:另一个是功能通用,不仅a ...
- Android中webView的基础使用(一)
WebView是View的一个子类,可以让你在activity中显示网页. 可以在布局文件中写入WebView:比如下面这个写了一个填满整个屏幕的WebView: <?xml version=& ...
- android 中webview调用js
1.android中利用webview调用网页上的js代码. Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true ...
- Android中webview跟JAVASCRIPT中的交互
在android的应用程序中,可以直接调用webview中的javascript代码,而webview中的javascript代码,也可以去调用ANDROID应用程序(也就是JAVA部分的代码).下面 ...
随机推荐
- UVA 11374 Airport Express SPFA||dijkstra
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...
- mongodb查询部分满足条件的列
db.tblorders.createIndex( { orderid : -1 },{background:true, name:"index_orderid"} ); db.o ...
- MAVEN Error: Using platform encoding (GBK actually) to copy filtered resources.....
环境:Maven3.2.5+MyEclipse 2015CI 现象:在Maven编译过程中出现错误信息:Using platform encoding (GBK actually) to copy f ...
- js cookie介绍和实例(用于自动登录,记住用户名等)
js cookie介绍和实例(用于自动登录,记住用户名等) 一.总结 1.cookie在客户端:因为js是最初是用来在客户端和服务器端进行通信使用的,所以客户端比如js可以操作cookie正常 2.c ...
- python3的函数
#摘自廖雪峰的程序教程 函数名是变量: 如abs()是一个求绝对值的函数, >>> x = abs(-10) >>> x 10 变量可以指向函数 用f指向函数abs ...
- [Angular2 Router] Resolving route data in Angular 2
From Article: RESOLVING ROUTE DATA IN ANGULAR 2 Github If you know Anuglar UI router, you must know ...
- Swift3.0 功能二 (表情键盘与图文混排)
随着iOS越来越多表情键盘以及图文混排的需求,本文运用Swift3.0系统的实现其功能以及封装调用方法,写的不好,如有错误望各位提出宝贵意见,多谢 项目源码地址: 相关知识点都有标识 项目源码地址 废 ...
- php curl header头
工作中第一次用到header做个记录 工作中需要在heaer里面加上 Authorization 用来验证身份 public function index() { $url = "http: ...
- 【Nutch2.2.1基础教程之6】Nutch2.2.1抓取流程 分类: H3_NUTCH 2014-08-15 21:39 2530人阅读 评论(1) 收藏
一.抓取流程概述 1.nutch抓取流程 当使用crawl命令进行抓取任务时,其基本流程步骤如下: (1)InjectorJob 开始第一个迭代 (2)GeneratorJob (3)FetcherJ ...
- 【solr基础教程之九】客户端 分类: H4_SOLR/LUCENCE 2014-07-30 15:28 904人阅读 评论(0) 收藏
一.Java Script 1.由于Solr本身可以返回Json格式的结果,而JavaScript对于处理Json数据具有天然的优势,因此使用JavaScript实现Solr客户端是一个很好的选择. ...