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显示内容的时候有点慢。

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

时间: 2024-10-11 13:47:35

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

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

一.Android中WebView的漏洞分析 最近在开发过程中遇到一个问题,就是WebView使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视,关于这个漏洞,这里就不多做解释了,可能有的同学早就了解了,本来想写一篇文章详细介绍一下,但是网上的知识太多了,而且都很详细,就没弄了,这里大致简单明了的说几句: 第一.漏洞产生的原因 这个漏洞导致的原因主要是因为Android中WebView中的JS访问本地方法的方式存在缺陷,我们做过交互的都知

Android中WebView获取网页中标题 ,内容, 图片的方法

如题,在Android中WebView获取网页中标题 ,内容, 图片的方法 首先是获取标题,在new WebChromeClient(){}中重写onReceivedTitle()方法 @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); // loge.e("__页面标题__"+title); } 获取内容,是参考的这边的 http

Android中WebView开发汇总

1 去掉WebView的白色背景 2 WebView的超时处理 3 WebView加载网络PDF资源 4 图片自适应WebView大小(铺满WebView) 5 WebView利用UserAgent传递SESSIONID 6 监听WebView滑动到底部 7 WebView长按后调用文字复制功能 8 Android硬件加速以及WebView的onPause,onResume,OnDestroy 9 WebView不能加载Twitter的问题 10 WebView加载本地SD卡上的图片 11 We

Android 中Webview 自适应屏幕

随笔 - 478  文章 - 3  评论 - 113 Android 中Webview 自适应屏幕 webview中右下角的缩放按钮能不能去掉 settings.setDisplayZoomControls(false); //隐藏webview缩放按钮 让Webview加载的页面居中显示有我知道的几种方法 第一种方法: WebSettings settings = webView.getSettings(); settings.setLayoutAlgorithm(LayoutAlgorith

Android中bitmap的相关处理

加载大图片 Options options=new Options(); options.inJustDecodeBounds=true;//不加载图片,只加载文件信息 //加载图片,获取到配置信息 BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/a.jpg",options); int width=options.outWidth;//获取到图片的真是宽度 int height=options.

Android中WebView的详细解释

Android中WebView的详细解释: 1. 概念: WebView(网络视图)能加载显示网页,可以将其视为一个浏览器.它使用了WebKit渲染引擎加载显示网页. 2. 使用方法: (1).实例化WebView组件: A.在Activity中实例化WebView组件.eg: WebView webView = new WebView(this); B.调用WebView的loadUrl()方法,设置WevView要显示的网页.eg: 互联网用:webView.loadUrl("http://

android 中webview的屏幕适配问题

两行代码解决WebView的屏幕适配问题 一个简单的方法,让网页快速适应手机屏幕,代码如下 1 2 WebSettings webSettings= webView.getSettings(); webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); 说明:LayoutAlgorithm 是一个枚举,用来控制html的布局,总共有三种类型: 大专栏  android 中webview的屏幕适配问题ng>NORMAL:正常显示,

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

http://www.cnblogs.com/leizhenzi/archive/2011/06/29/2093636.html 1.android中利用webview调用网页上的js代码. Android 中可以通过webview来实现和js的交互,在程序中调用js代码,只需要将webview控件的支持js的属性设置为true,,然后通过loadUrl就可以直接进行调用,如下所示: mWebView.getSettings().setJavaScriptEnabled(true); mWebV

Android中webView的基础使用(一)

WebView是View的一个子类,可以让你在activity中显示网页. 可以在布局文件中写入WebView:比如下面这个写了一个填满整个屏幕的WebView: 1 <?xml version="1.0" encoding="utf-8"?> 2 <WebView xmlns:android="http://schemas.android.com/apk/res/android" 3 android:id="@+id