Markdown版本笔记 | 个人GitHub首页 | 个人博客 | 个人微信 | 个人邮箱 |
---|---|---|---|---|
MyAndroidBlogs | baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
WebView 加载网页 加载资源 总结 MDjavascript
demophp
使用 loadUrl 不但浪费流量,并且加载起来也慢,因此能够将页面提早写好放到项目中,这样就能够用 loadData 更快的加载页面,用户体验会好些。html
void loadData(String data, String mimeType, String encoding)
Loads the given data into this WebView using a 'data' scheme URL.
使用 'data' 方案 URL 将给定的数据加载到此WebView中。java
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)'.
请注意,JavaScript的"同源策略"意味着,在使用此方法加载的页面中运行的脚本,将没法访问使用除了使用 data方案 以外的任何内容,包括http。android
To avoid this restriction, use loadDataWithBaseURL() with an appropriate base URL.
为避免此限制,请使用带有适当的base URL的loadDataWithBaseURL()方法。git
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'.
encoding参数用于指定数据是不是采用base64编码或URL编码。若是数据为base64编码,则编码参数的值必须为'base64'。github
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.
对于此参数的其余全部可能值,包括null,假定数据在安全URL字符范围内使用八位字节的ASCII编码,而且,在此范围之外的字节使用标准的 %xx 十六进制编码的八位字节的URL。web
For example, '#', '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.
例如, '#', '%', '\', '?'应分别由%23,%25,%27,%3f代替。api
The 'data' scheme URL formed by this method uses the default US-ASCII charset.
由此方法造成的'data' 方案 URL使用默认的US-ASCII字符集。浏览器
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.
若是须要设置不一样的字符集,则应该造成一个'data' 方案 URL,它 显式 地在URL的 mediatype 部分 指定 一个charset 参数,或者也能够经过调用loadUrl代替。
Note that the charset obtained from the mediatype portion of a data URL always overrides that specified in the HTML or XML document itself.
请注意,从数据URL的 mediatype部分 获取的字符集,老是覆盖HTML或XML文档自己指定的字符集。
在使用 loadData 方法时,若是按照官网文档样式去写,当出现中文时中文部分会出现乱码,即便指定“utf-8”、“gbk”、“gb2312”也都同样。
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;
错误方式一:
webview.loadData(data, "text/html", "UTF8");
错误方式二:
webview.loadData(data, "text/html", "base64");
正确方式一:用loadData去加载
webview.loadData(data, "text/html; charset=UTF-8", "encoding能够是base64以外的任何内容");
正确方式二:用loadDataWithBaseURL去加载
webview.loadDataWithBaseURL(null, data, "text/html", "UTF-8", null);
结论
对于loadData中的encoding参数的值:
此方法实际上比loadData用途普遍的多,也是官方推荐使用的方法。
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头中发送。
此方法中的第一个参数baseUrl的值的做用是:指定你第二个参数data中数据是以什么地址为基准的。
这个参数是很是有用、很是重要的,由于data中的数据可能会有超连接或者是image元素,而不少网站中使用的地址都是相对路径,若是没有指定baseUrl,webview将访问不到这些资源。估计这就是文档中说的:JS的"同源策略"。
JavaScript's Same Origin Policy:
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没有指定,那么这两张图片将显示不出来,由于这里两个图片的地址是相对路径,不指定baseUrl时根本找不到这两张图片。
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,指定为从name到value的映射。
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的默认值所覆盖。
void postUrl (String url, byte[] postData)
Loads the URL with postData using "POST" method into this WebView.
If url is not a network URL, it will be loaded with loadUrl(String) instead, ignoring the postData param.
String url = "http://tapi.95xiu.com/app/pay/weixinmiao/user_pay.php" ; String postData= "uid=" + uid + "&session_id=" + session_id + "&total_fee="+total_fee; webview.postUrl(url , EncodingUtils.getBytes(postData, "base64"));
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线程上进行回调。
加载assets下的资源
webView.loadUrl("file:///android_asset/" + "h5/test.html");
或
String data = "<html><body>包青天<p/><img src='icon.jpg' /></body></html>" + "<p/>" + time; webView.loadDataWithBaseURL("file:///android_asset/", data, "text/html", "utf-8", null);
加载 res/drawable 或 res/mipmap 或 res/raw 下的资源
webView.loadUrl("file:///android_res/" + "drawable/ic_launcher"); webView.loadUrl("file:///android_res/" + "mipmap/ic_launcher"); webView.loadUrl("file:///android_res/" + "raw/test");
或
data = "<html><body>包青天<p/><img src='drawable/icon' /></body></html>" + "<p/>" + time; webView.loadDataWithBaseURL("file:///android_res/", data, "text/html", "utf-8", null);
加载SD卡中的资源
String FILE_BASE_SIMPLE = "file://" + Environment.getExternalStorageDirectory().getAbsolutePath()+ "/";//【file:///sdcard/】 webView.loadUrl(FILE_BASE_SIMPLE + "test.html");//【file:///storage/emulated/0/test.html】或【file:///sdcard/test.html】
或
data = "<html><body>包青天<p/><img src='icon.png' /></body></html>" + "<p/>" + time; webView.loadDataWithBaseURL(FILE_BASE_SIMPLE, data, "text/html", "utf-8", null);
演示load不一样资源的方法
public class LoadUrl_DataActivity extends ListActivity { private WebView webView; private boolean b; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] array = {"0、loadData时中文乱码问题,错误解决方案", "一、loadData时中文乱码问题,正确解决方案", "二、演示loadDataWithBaseURL方法中,参数baseUrl的做用", "三、加载assets下的资源", "四、加载res/drawable下的资源", "五、加载res/raw下的资源", "六、加载SD卡中的资源", "七、加载网页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>包青天<p/><a href=http://www.baidu.com>百度</a></body></html>" + "<p/>" + time; b = !b; Toast.makeText(this, "" + b, Toast.LENGTH_SHORT).show(); 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", "encoding能够是base64以外的任何内容"); else webView.loadDataWithBaseURL(null, data, "text/html", "utf-8", null); break; case 2://演示loadDataWithBaseURL方法中,参数baseUrl的做用 String baseUrl = b ? null : "http://img.mmjpg.com";//不设置baseUrl时,data2里面的两张图片将显示不出来 String data2 = "这里两个图片的地址是相对路径<img src='/2017/936/5.jpg' /><p/><img src='/2015/74/35.jpg' />"; webView.loadDataWithBaseURL(baseUrl, data2, "text/html", "utf-8", null); break; case 3://加载assets下的资源 data = "<html><body>包青天<p/><img src='icon.jpg' /></body></html>" + "<p/>" + time; if (b) webView.loadUrl(URLUtils.ASSET_BASE + "h5/test.html"); else webView.loadDataWithBaseURL(URLUtils.ASSET_BASE, data, "text/html", "utf-8", null); break; case 4://加载res/drawable 或 res/mipmap下的资源。不会区分drawable与drawable-***,但会区分drawable和mipmap data = "<html><body>包青天<p/><img src='drawable/icon.不会校验文件后缀名' /></body></html>" + "<p/>" + time; if (b) webView.loadUrl(URLUtils.RESOURCE_BASE + "mipmap/ic_launcher");//建议直接省略文件后缀名 else webView.loadDataWithBaseURL(URLUtils.RESOURCE_BASE, data, "text/html", "utf-8", null); break; case 5://加载res/raw下的资源,和res/drawable同样,都属于Resources资源文件 data = "<html><body>包青天<p/><img src='raw/icon.jpg' /></body></html>" + "<p/>" + time; if (b) webView.loadUrl(URLUtils.RESOURCE_BASE + "raw/test"); else webView.loadDataWithBaseURL(URLUtils.RESOURCE_BASE, data, "text/html", "utf-8", null); break; case 6://加载SD卡中的资源。注意,若是提示【net::ERR_ACCESS_DENIED】,是由于没有申请权限 data = "<html><body>包青天<p/><img src='icon.png' /></body></html>" + "<p/>" + time; if (b) webView.loadUrl(URLUtils.FILE_BASE_SIMPLE + "test.html"); else webView.loadDataWithBaseURL(URLUtils.FILE_BASE_SIMPLE, data, "text/html", "utf-8", null); break; case 7://加载网页http资源 webView.loadUrl(b ? "http://www.meituba.com/" : "http://img.mmjpg.com/2017/936/5.jpg"); break; } } }
<!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>res下的图片 src='file:///android_res/drawable/ic_launcher'</p> <img src='file:///android_res/drawable/ic_launcher' alt="" width="100%p"/> <p>assets下的图片 src='file:///android_asset/icon.jpg'</p> <img src='file:///android_asset/icon.jpg' alt="" width="100%p"/> <p>SD卡下的图片 src='file:///sdcard/icon.png'</p> <img src='file:///sdcard/icon.png' alt="" width="100%p"/> <p> <a href=" tel:15031257363">电话</a> <a href="sms:15031257363">短信</a> <a href="mailto:1242599243@qq.com">邮件</a> </p> </body> </html>
2017-7-27