WebView load**方法 加载资源【总结】


loadData【API】

void loadData(String data, String mimeType, String encoding) Loads the given data into this WebView using a 'data' scheme URL.
  • Loads the given data into this WebView using a 'data' scheme URL.
    使用'data' scheme URL将给定的数据加载到此WebView中。
  • Note that JavaScript's same origin policy means that script running in a page loaded using this method will be unable to access content loaded using any scheme other than 'data', including 'http(s)'. To avoid this restriction, use loadDataWithBaseURL() with an appropriate base URL.
    请注意,JavaScript的"同源策略"意味着,在使用此方法加载的页面中运行的脚本,将无法访问使用除data'之外的任何内容(包括“http”)加载的内容。为避免此限制,请使用带有适当基本URL的loadDataWithBaseURL方法。
  • The encoding parameter specifies whether the data is base64 or URL encoded. If the data is base64 encoded, the value of the encoding parameter must be 'base64'. For all other values of the parameter, including null, it is assumed that the data uses ASCII encoding for octets inside the range of safe URL characters and use the standard %xx hex encoding of URLs for octets outside that range. For example, '#', '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.
    encoding参数指定数据是base64还是URL进行编码。如果数据为base64编码,则编码参数的值必须为'base64'。对于参数的其他所有值(包括null),
    假定数据采用ASCII码在安全范围的字节的URL字符编码,使用标准% XX hex编码的URL范围以外的字节。例如, '#', '%', '\', '?'应分别由%23,%25,%27,%3f代替。
  • The 'data' scheme URL formed by this method uses the default US-ASCII charset. If you need to set a different charset, you should form a 'data' scheme URL which explicitly specifies a charset parameter in the mediatype portion of the URL and call loadUrl(String) instead. Note that the charset obtained from the mediatype portion of a data URL always overrides that specified in the HTML or XML document itself.
    由此方法形成的'data' scheme URL使用默认的US-ASCII字符集。如果需要设置不同的字符集,则应该形成一个'data' scheme URL,该URL显式地在URL的mediatype部分指定一个charset参数,并调用loadUrl。请注意,从数据URL的mediatype部分获取的字符集,总是覆盖HTML或XML文档本身指定的字符集。
Parameters
  • data String: a String of data in the given encoding
  • mimeType String: the MIME type of the data, e.g. 'text/html'
  • encoding String: the encoding of the data

loadData【案例】

使用loadUrl不但浪费流量,而且加载起来也慢,所以可以将页面提前写好放到项目中,这样就可以用loadData更快的加载页面,用户体验会好些。
在使用 loadData方法时,如果按照官网文档样式去写,当出现中文时 中文部分 会出现乱码,即使指定“utf-8”、“gbk”、“gb2312”也都一样。
String data= "<html><body>你好:<b>包青天</b> <p/>请登录</body></html>";
webview.loadData(data, "text/html", "UTF8");
另外,即使通过webview.getSettings().setDefaultTextEncodingName("UTF-8");也没任何卵用(其实,其默认就是utf-8)。
其实,只要好好看一些官方文档中对loadData的说明,就会发现,最后那个指定编码的encoding参数的值,除了设置为【base64】可能会有影响外,设置为null或其他任何值都是没有影响的。
有效的解决方法为:
webview.loadData(data, "text/html; charset=UTF-8", "你妹");//encoding的值除了【base64】,其他值都没影响
当然,也可以改用loadDataWithBaseURL去加载:
webview.loadDataWithBaseURL(null, data, "text/html", "UTF-8", null);

loadDataWithBaseURL【API】

void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)
  • Loads the given data into this WebView, using baseUrl as the base URL for the content. 
    将给定的数据加载到此WebView中,使用baseUrl作为内容的基本URL。
    The base URL is used both to resolve relative URLs and when applying JavaScript's same origin policy. 
    基本URL既用于解析相对URL,又用于应用JavaScript的同源策略。
    The historyUrl is used for the history entry.
     historyUrl用于历史记录条目。
  • Note that content specified in this way can access local device files (via 'file' scheme URLs) only if baseUrl specifies a scheme other than 'http', 'https', 'ftp', 'ftps', 'about' or 'javascript'.
    请注意,只有在baseUrl指定了除“http”,“https”,“ftp”,“ftps”,“about”或“javascript”之外的scheme时,以此方式指定的内容才能访问本地设备文件(通过 'file' scheme URL)”。
  • If the base URL uses the data scheme, this method is equivalent to calling loadData() and the historyUrl is ignored, and the data will be treated as part of a data: URL. 
    如果baseUrl使用data scheme,则此方法相当于调用loadData方法,并忽略historyUrl,并且data将被视为 data:URL 的一部分。
    If the base URL uses any other scheme, then the data will be loaded into the WebView as a plain string (i.e. not part of a data URL) and any URL-encoded entities in the string will not be decoded.
    如果baseUrl使用任何其他scheme,则data将作为纯字符串(即不是 data URL 的一部分)加载到WebView中,并且字符串中的任何URL编码实体将不被解码。
  • Note that the baseUrl is sent in the 'Referer' HTTP header when requesting subresources (images, etc.) of the page loaded using this method.
    请注意,当请求使用此方法,加载页面的子资源(图像等)时,baseUrl会在 'Referer' HTTP头中发送。
Parameters
  • baseUrl String: the URL to use as the page's base URL. If null defaults to 'about:blank'.
  • data String: a String of data in the given encoding
  • mimeType String: the MIMEType of the data, e.g. 'text/html'. If null, defaults to 'text/html'.
  • encoding String: the encoding of the data
  • historyUrl String: the URL to use as the history entry. If null defaults to 'about:blank'. If non-null, this must be a valid URL.

loadDataWithBaseURL【案例】

此方法实际上比loadData用途广泛的多,也是官方推荐使用的方法。
其中,最重要的是:此方法中的第一个参数baseUrl的值的作用是,指定你第二个参数data中数据是以什么地址为基准的。
为什么非常重要呢?因为data中的数据可能会有超链接或者是image元素,而很多网站中使用的地址都是相对路径,如果没有指定baseUrl,webview将访问不到这些资源。估计这就是文档中说的:JS的" 同源策略 "。

例如
String data = "这里两个图片的地址是相对路径<img src='/2015/74/33.jpg' /><p/><img src='/2015/74/35.jpg' />";
String baseUrl = "http://img.mmjpg.com";
webview.loadDataWithBaseURL(baseUrl, data, "text/html", "utf-8", null);
如果baseUrl没有指定,那么这两张图片将显示不出来。

PS:JavaScript's Same Origin Policy( 同源策略 )
同源策略的精髓很简单:它认为自任何站点装载的信赖内容是不安全的。当被浏览器半信半疑的脚本运行在沙箱时,它们应该只被允许访问来自同一站点的资源,而不是那些来自其它站点可能怀有恶意的资源。

loadUrl【API】

void loadUrl(String url)Loads the given URL.
void loadUrl(String url, Map<String, String> additionalHttpHeaders)Loads the given URL with the  specified additional HTTP headers.
  • Map: the additional headers to be used in the HTTP request for this URL, specified as a map from name to value.
    要在此URL的HTTP请求中使用的附加headers,指定为从名称到值的映射。
  • Note that if this map contains any of the headers that are set by default by this WebView, such as those controlling caching, accept types or the User-Agent, their values may be overridden by this WebView's defaults.  
    请注意,如果此映射包含此WebView默认设置的任何headers,例如控制缓存,接受类型或User-Agent的标头,则该值可能会被该WebView的默认值覆盖。

evaluateJavascript【API】

void evaluateJavascript (String script,  ValueCallback<String> resultCallback)
  • Asynchronously evaluates JavaScript in the context of the currently displayed page. If non-null, |resultCallback| will be invoked with any result returned from that execution. This method must be called on the UI thread and the callback will be made on the UI thread.
    在当前显示页面的上下文中异步执行JavaScript。 如果非空,| resultCallback | 将使用从该执行返回的任何结果来调用它。 必须在UI线程上调用此方法,并在UI线程上进行回调。
  • Compatibility note. Applications targeting N or later, JavaScript state from an empty WebView is no longer persisted across navigations like loadUrl(String). For example, global variables and functions defined before calling loadUrl(String) will not exist in the loaded page. Applications should use addJavascriptInterface(Object, String) instead to persist JavaScript objects across navigations.
    兼容性说明 定位为N或更高版本的应用程序,空载WebView中的JavaScript状态不再在诸如loadUrl(String)之类的导航中保留。 例如,在加载的页面中不会存在调用loadUrl(String)之前定义的全局变量和函数。 应用程序应该使用addJavascriptInterface(Object,String)来跨导航来维护JavaScript对象。
参数:
  • script String: the JavaScript to execute.要执行的JavaScript。
  • resultCallback ValueCallback: 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。

加载各种类型的资源方法总结

加载assets下的资源

// to refer to bar.png under your package's asset/foo/ directory, use"file:///android_asset/foo/bar.png".
String ASSET_BASE = "file:///android_asset/";//参见URLUtil.ASSET_BASE
webView.loadUrl(ASSET_BASE + "h5/test.html");
webView.loadDataWithBaseURL(ASSET_BASE, "<img src='icon.jpg' />", "text/html", "utf-8", null);

加载res/drawable下的资源

// to refer to bar.png under your package's res/drawable/ directory, use "file:///android_res/drawable/bar.png".
// Use "drawable" to refer to "drawable-hdpi" directory as well.
String RESOURCE_BASE = "file:///android_res/";//参见URLUtil.RESOURCE_BASE
webView.loadUrl(RESOURCE_BASE + "mipmap/ic_launcher.任意后缀名都可以");//res资源不会检索文件后缀名
webView.loadDataWithBaseURL(RESOURCE_BASE, "<img src='drawable/icon.jpg' />", "text/html", "utf-8", null);

加载res/raw下的资源

webView.loadUrl("file:///android_res/" + "raw/test.html");//res资源不会检索文件后缀名
webView.loadDataWithBaseURL("file:///android_res/", "<img src='raw/icon.jpg' />", "text/html", "utf-8", null);

加载SD卡中的资源

String FILE_BASE = "file://";//参见URLUtil.FILE_BASE。如果提示【net::ERR_ACCESS_DENIED】,是没有申请权限
String file = FILE_BASE + Environment.getExternalStorageDirectory().getAbsolutePath() + "/h5/test.html";
webView.loadUrl(file);//【file:///storage/emulated/0/h5/test.html】或【file:///"sdcard/h5/test.html】
webView.loadDataWithBaseURL(FILE_BASE, "<img src='sdcard/Pictures/icon.jpg' />", "text/html", "utf-8", null);

一个完整的案例

public class LoadTestActivity extends ListActivity {
	private WebView webView;
	private boolean b;

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		String[] array = {"0、loadData时中文乱码问题,错误解决方案",
				"1、loadData时中文乱码问题,正确解决方案",
				"2、演示loadDataWithBaseURL方法中,参数baseUrl的作用",
				"3、加载assets下的资源",
				"4、加载res/drawable下的资源",
				"5、加载res/raw下的资源",
				"6、加载SD卡中的资源",
				"7、加载网页http资源",};
		setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new ArrayList<>(Arrays.asList(array))));
		webView = new WebView(this);
		getListView().addFooterView(webView);
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		String time = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss SSS", Locale.getDefault()).format(new Date());
		String data = "<html><body>你好:<b>包青天</b> <p/>请登录</body></html>" + "<p/>" + time;

		b = !b;
		switch (position) {
			case 0://loadData时中文乱码问题,错误解决方案
				String encoding = b ? "UTF8" : "base64";//encoding参数的值,设置为null或其他任何值(除了"base64")都是没有影响的
				webView.loadData(data, "text/html", encoding);//如果不是采用的base64编码,那么绝不能设置为【base64】
				break;
			case 1://loadData时中文乱码问题,正确解决方案
				if (b) webView.loadData(data, "text/html; charset=UTF-8", "同样可以设置为除base64外的任何东西");
				else webView.loadDataWithBaseURL(null, data, "text/html", "utf-8", null);
				break;
			case 2://演示loadDataWithBaseURL方法中,参数baseUrl的作用
				String baseUrl = b ? null : "http://img.mmjpg.com";
				String data2 = "这里两个图片的地址是相对路径<img src='/2017/936/5.jpg' /><p/><img src='/2015/74/35.jpg' />";
				webView.loadDataWithBaseURL(baseUrl, data2, "text/html", "utf-8", null);//不设置baseUrl时,这两张图片将显示不出来
				break;
			case 3://加载assets下的资源
				// to refer to bar.png under your package's asset/foo/ directory, use"file:///android_asset/foo/bar.png".
				String ASSET_BASE = "file:///android_asset/";//参见URLUtil.ASSET_BASE
				if (b) webView.loadUrl(ASSET_BASE + "h5/test.html");
				else webView.loadDataWithBaseURL(ASSET_BASE, "<img src='icon.jpg' />", "text/html", "utf-8", null);
				break;
			case 4://加载res/drawable下的资源
				// to refer to bar.png under your package's res/drawable/ directory, use "file:///android_res/drawable/bar.png".
				// Use "drawable" to refer to "drawable-hdpi" directory as well.
				String RESOURCE_BASE = "file:///android_res/";//参见URLUtil.RESOURCE_BASE
				if (b) webView.loadUrl(RESOURCE_BASE + "mipmap/ic_launcher.任意后缀名都可以");//res资源不会检索文件后缀名
				else webView.loadDataWithBaseURL(RESOURCE_BASE, "<img src='drawable/icon.jpg' />", "text/html", "utf-8", null);
				break;
			case 5://加载res/raw下的资源
				if (b) webView.loadUrl("file:///android_res/" + "raw/test");//res资源不会检索文件后缀名
				else webView.loadDataWithBaseURL("file:///android_res/", "<img src='raw/icon.jpg' />", "text/html", "utf-8", null);
				break;
			case 6://加载SD卡中的资源
				String FILE_BASE = "file://";//参见URLUtil.FILE_BASE。如果提示【net::ERR_ACCESS_DENIED】,是没有申请权限
				String file = FILE_BASE + Environment.getExternalStorageDirectory().getAbsolutePath() + "/h5/test.html";
				if (b) webView.loadUrl(file);//【file:///storage/emulated/0/h5/test.html】或【file:///"sdcard/h5/test.html】
				else webView.loadDataWithBaseURL(FILE_BASE, "<img src='sdcard/Pictures/icon.jpg' />", "text/html", "utf-8", null);
				break;
			case 7://加载网页http资源
				webView.getSettings().setUseWideViewPort(true);
				webView.getSettings().setLoadWithOverviewMode(true);
				webView.setWebViewClient(new WebViewClient() {
					@Override
					public boolean shouldOverrideUrlLoading(WebView view, String url) {
						view.loadUrl(url);//不去调用系统浏览器, 而是在本WebView中跳转
						return true;
					}
				});
				webView.loadUrl(b ? "http://www.meituba.com/" : "http://img.mmjpg.com/2017/936/5.jpg");
				break;
		}
	}
}
参考HTML代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <meta name="Description" content="Description"/>
    <meta name="Keywords" content="Keywords"/>
    <title>title</title>
</head>
<body>
<h1>测试</h1>
<p>段落,assets</p>

<p>src='file:///android_res/drawable/ic_launcher'</p>
<img src='file:///android_res/drawable/ic_launcher' alt="" width="100%p"/>

<p>src='../icon.jpg'</p>
<img src='../icon.jpg' alt="" width="100%p"/>

<p>
    <a href=" tel:15031257363">电话</a>&nbsp;
    <a href="sms:15031257363">短信</a>&nbsp;
    <a href="mailto:1242599243@qq.com">邮件</a>
</p>
</body>
</html>
2017-7-27




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值