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