近期做的项目中,遇到个非常棘手的问题:

客户给我的数据是有限制的,因此,在返回某条详细页面内容的时候,他仅仅能给我一个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显示内容的时候有点慢。

源码下载地址:http://download.csdn.net/detail/xxm282828/7362539

Android中WebView的相关使用的更多相关文章

  1. Android中WebView的JavaScript代码和本地代码交互的三种方式

    一.Android中WebView的漏洞分析最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视 ...

  2. Android中webView和网页的交互

     Android中webView和网页的交互 Android中webView跟网页的交互式通过JavaScript进行的.具体步骤: 1.创建JavaScript,在点击的时候调用JavaScript ...

  3. Android 中Webview 自适应屏幕

    随笔 - 478  文章 - 3  评论 - 113 Android 中Webview 自适应屏幕   webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomCon ...

  4. android 中webview的屏幕适配问题

    两行代码解决WebView的屏幕适配问题 一个简单的方法,让网页快速适应手机屏幕,代码如下 1 2 WebSettings webSettings= webView.getSettings(); we ...

  5. Android中webview和js之间的交互(转)

    http://www.cnblogs.com/leizhenzi/archive/2011/06/29/2093636.html 1.android中利用webview调用网页上的js代码. Andr ...

  6. Android中Webview使用自定义的javascript进行回调

    先说为什么需要讨论这个问题. 现在很多的手机应用,都可能会直接嵌入一个web页面.这样做的好处:一个是功能更新方便,维护起来容易,只需要维护服务器的页面即可,不需要更新客户端:另一个是功能通用,不仅a ...

  7. Android中webView的基础使用(一)

    WebView是View的一个子类,可以让你在activity中显示网页. 可以在布局文件中写入WebView:比如下面这个写了一个填满整个屏幕的WebView: <?xml version=& ...

  8. android 中webview调用js

    1.android中利用webview调用网页上的js代码. Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true ...

  9. Android中webview跟JAVASCRIPT中的交互

    在android的应用程序中,可以直接调用webview中的javascript代码,而webview中的javascript代码,也可以去调用ANDROID应用程序(也就是JAVA部分的代码).下面 ...

随机推荐

  1. Remove Duplicates from Sorted Array [Python]

    Given a sorted array, remove the duplicates in place such that each element appear only once and ret ...

  2. WPF遍历当前容器中某种控件的方法

    原文:WPF遍历当前容器中某种控件的方法 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/m0_37591671/article/details/79 ...

  3. swift学习第十一天:类的定义

    一: 主要内容 类的介绍和定义 类的属性 类的构造函数 一. 类的介绍和定义 Swift也是一门面向对象开发的语言 面向对象的基础是类,类产生了对象 在Swift中如何定义类呢? class是Swif ...

  4. [TypeScript] Find the repeated item in an array using TypeScript

    Say you have an array that has at least one item repeated. How would you find the repeated item. Thi ...

  5. ios开发之坐标系转换

    1:坐标系转换最核心的问题就是:比较两个坐标是否包含,或者是重叠等,最主要的问题是先将两个坐标转换到同一个坐标系下再去比较.第一步先确定矩形框在某个view坐标系下的frame(该矩形框是以该view ...

  6. js进阶正则表达式6转义字符(加\转义)(.符号)(|符号)

    js进阶正则表达式6转义字符(加\转义)(.符号)(|符号) 一.总结 转义字符:{} () / $ # & * . ....... //3.特殊字符,都要加转义\ 点符号:var reg2= ...

  7. 【codeforces 760C】Pavel and barbecue

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. windows下 管理员身份启动java进程

    http://blog.csdn.net/zhuyijian135757/article/details/38234757

  9. [Docker] Container & image (docker run)

    image: stopped container Run a container: docker run -d --name web -p : nigelpoulton/pluralsight-doc ...

  10. 基于 OAuth 安全协议的 Java 应用编程

    OAuth 简介 OAuth 是由 Blaine Cook.Chris Messina.Larry Halff 及 David Recordon 共同发起的,目的在于为 API 访问授权提供一个安全. ...