Android WebView 詳解
本文記錄 Android
中 WebView
控制元件的相關使用,不斷完善中…
主要包括:
- 基本屬性的配置
WebView
快取相關內容Java
與Js
的互動WebView
開啟本地應用(支付寶等)- 載入網路連結,本地
sd
卡路徑,assert
目錄路徑的方法 WebView
支援下載等其它一些內容
基本配置彙總
彙總的記錄一下 WebView
的配置方法,重要的屬性後面會展開說明。
@SuppressLint("SetJavaScriptEnabled")
public static void initWebViewSettings(WebView mWebView) {
//支援獲取手勢焦點
mWebView.requestFocusFromTouch();
// 觸覺反饋,暫時沒發現用處在哪裡
mWebView.setHapticFeedbackEnabled(false);
WebSettings settings = mWebView.getSettings();
// 支援外掛
settings.setPluginState(WebSettings.PluginState.ON);
// 允許js互動
settings.setJavaScriptEnabled(true);
// 設定WebView是否可以由 JavaScript 自動開啟視窗,預設為 false
// 通常與 JavaScript 的 window.open() 配合使用。
settings.setJavaScriptCanOpenWindowsAutomatically(true);
// 允許中文編碼
settings.setDefaultTextEncodingName("UTF-8");
// 使用大檢視,設定適應螢幕
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
// 支援多視窗
settings.setSupportMultipleWindows(true );
// 隱藏自帶縮放按鈕
settings.setBuiltInZoomControls(false);
// 支援縮放
settings.setSupportZoom(true);
// 設定可訪問檔案
settings.setAllowFileAccess(true);
// 當WebView呼叫requestFocus時為WebView設定節點
settings.setNeedInitialFocus(true);
//支援自動載入圖片
settings.setLoadsImagesAutomatically(true);
// 指定WebView的頁面佈局顯示形式,呼叫該方法會引起頁面重繪。
// NORMAL,SINGLE_COLUMN 過時, NARROW_COLUMNS 過時 ,TEXT_AUTOSIZING
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
// 從Lollipop(5.0)開始WebView預設不允許混合模式,https當中不能載入http資源,需要設定開啟
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
}
WebView 快取
清除快取,true
表示清除磁碟快取,這個方法是全域性的,也就是說會清除掉整個應用所有的 網頁快取。
mWebView.clearCache(true);
清除歷史記錄
mWebView.clearHistory();
網上有介紹說,設定快取的目錄,清除快取時刪除掉快取檔案,但是使用下面的方法設定快取路徑後,發現檔案並沒有快取到指定的目錄,不知道是怎麼回事?求指教
快取模式 | 描述 |
---|---|
LOAD_DEFAULT | 預設的快取使用模式。在進行頁面前進或後退的操作時,如果快取可用並未過期就優先載入快取,否則從網路上載入資料。這樣可以減少頁面的網路請求次數。 |
LOAD_CACHE_ELSE_NETWORK | 只要快取可用就載入快取,哪怕它們已經過期失效。如果快取不可用就從網路上載入資料。 |
LOAD_NO_CACHE | 不載入快取,只從網路載入資料。 |
LOAD_CACHE_ONLY | 不從網路載入資料,只從快取載入資料。 |
private static void initWebViewCache(WebView mWebView) {
String cachePath = new File(Environment.getExternalStorageDirectory()
, "webCache").getAbsolutePath();
WebSettings settings = mWebView.getSettings();
settings.setAppCacheEnabled(true);
settings.setAppCachePath(cachePath);
settings.setDatabaseEnabled(true);
// 過時
settings.setDatabasePath(cachePath);
// 開啟dom快取
settings.setDomStorageEnabled(true);
// 載入模式
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
// 快取最大值,過時
settings.setAppCacheMaxSize(1000 * 1024);
}
載入 Url
載入網路路徑,headers
不是必選的
Map<String,String> headers = new HashMap<>();
headers.put("auth","110");
mWebView.loadUrl("https://www.baidu.com/",headers);
載入 assert
路徑
// WebViewUtil.java
public static String getAssertUrl(String fileUrl) {
return "file:///android_asset/" + fileUrl;
}
mWebView.loadUrl(WebViewUtil.getAssertUrl("index.html"));
載入 sd
卡路徑
// WebViewUtil.java
public static String getSdUrl(String fileUrl) {
return "file://" + Environment.getExternalStorageDirectory() + "/" + fileUrl;
}
mWebView.loadUrl(WebViewUtil.getSdUrl("index.html"));
Js 呼叫 Java
Java
與 Js
互動需要定義一個帶有 @JavascriptInterface
註解方法的物件,如下:
public class JsBridge {
@JavascriptInterface
public void toast(String msg) {
ToastUtils.show(msg);
}
@JavascriptInterface
public void log(String msg) {
Log.e(TAG, msg);
}
}
使用 JsBridge
連線 Java
和 Js
,使用 mWebView.addJavascriptInterface(obj, name);
方法。
- obj:帶有
JavascriptInterface
註解方法的物件例項。 - name:一個標誌符,js 將會使用該標誌來呼叫 java 層的方法。
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JsBridge(), "android");
在新增呼叫介面時,我們添加了一個標記,如上面程式碼中新增的是 android
,它相當於呼叫介面物件的一個別名,因此在 js
中呼叫 java
方法時,只需要使用 window
物件,如下:
window.android.log('test js invoke java method');
Java 呼叫 Js
使用 java
呼叫 js
方法相對簡單,假如在 js
中應該宣告如下 function
,
<script>
// 有參無返回值
function funcParam(param){
alert(param+"");
}
// 有參有返回值
function newFunc(param1,param2,param3){
alert((param1 + param2) + " " + param3);
return param3;
}
</script>
在 java
層呼叫時只需 loadUrl("Javascript:js方法名())
即可,但是 Android 4.4 之後在呼叫 js
方法時可以獲取返回值,寫一個方法相容一下
public static final String JS_FUNC_PREFIX = "javascript:";
public void invokeJs(String jsFunc, final ValueCallback<String> callback) {
if (!jsFunc.startsWith(JS_FUNC_PREFIX)) {
jsFunc = JS_FUNC_PREFIX + jsFunc;
}
// api 19
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebView.evaluateJavascript(jsFunc, callback);
} else {
mWebView.loadUrl(jsFunc);
}
}
在與 js
進行引數傳遞時,基本資料型別可以直接傳遞,字串型別要使用引號包含,而且直接拼接字串不太好,因此寫一個簡化構建 js
方法,自動按順序進行引數的拼接。
// 建立一個 js 方法
public static String generateJsFunc(String funcName, Object... params) {
StringBuilder sb = new StringBuilder(funcName).append("(");
for (int i = 0; i < params.length; i++) {
if (params[i] != null) {
if (params[i] instanceof String) {
sb.append("'").append(params[i]).append("'");
} else {
sb.append(params[i]);
}
if (i != params.length - 1) {
sb.append(",");
}
}
}
sb.append(")");
return sb.toString();
}
簡單呼叫
// 呼叫有參有返回值的方法
String jsFunc = JsBridge.generateJsFunc("newFunc", "str", 100, 100);
mJsBridge.invokeJs(jsFunc, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.e(TAG, "value = " + value);
}
});
// 呼叫有參無返回值方法
String funcParam = JsBridge.generateJsFunc("funcParam", 100);
mJsBridge.invokeJs(funcParam, null);
攔截 Url 開啟應用(支付寶)
主要原理是由於某些應用會暴露一些頁面出來供別的 app 喚起,因此我們只需要攔截這種 Url
,然後使用 intent
開啟即可,下面以支付寶為例說明:
前端使用支付寶進行支付時,需要開啟手機支付寶客戶端,斷點看到支付寶會載入一個 scheme
為 alipays
的url,連結中配置了支付的相關資訊,客戶端要做的就是攔截該 Url
,使用 intent
開啟支付寶。
當 html
載入網頁之前會先走 shouldOverrideUrlLoading()
方法,此時截斷不使用 webView
載入,而是使用 intent
開啟,此方法不僅適用支付寶,也適用開啟其他應用。
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// 如果不使用 intent 覆蓋載入這個連結,就走原來
if (!shouldOverrideIntentUrl(getContext(), url)) {
view.loadUrl(url, Api.makeHttpHeaders(getContext()));
}
return true;
}
});
private boolean shouldOverrideIntentUrl(Context context, String url) {
Uri uri = Uri.parse(url);
if (uri.getScheme().equals("alipays")) {
try {
Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setComponent(null);
intent.setSelector(null);
context.startActivity(intent);
return true;
} catch (URISyntaxException e) {
e.printStackTrace();
return false;
}
}
return false;
}
支援下載連結
當網頁中載入一個下載的連結,如 http://xxx.apk
這種連結,會走 shouldOverrideUrlLoading()
方法,但是,它是無法載入一個網頁的,結果就是沒有任何反應,此時需要設定 DownloadListener
,需要下載的連結會進入監聽,你可以在監聽中自己進行網路下載儲存到檔案,下面我使用直接開啟瀏覽器的方式,更簡單一些。
public static void setDefDownloadListener(final WebView webView) {
webView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent,
String contentDisposition,
String mimetype,
long contentLength) {
//去下載
Intent intent = new Intent(Intent.ACTION_VIEW);
String downLoadUrl = url;
if (!downLoadUrl.contains("http://")) {
downLoadUrl = "http://" + downLoadUrl;
}
intent.setData(Uri.parse(downLoadUrl));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
webView.getContext().startActivity(intent);
}
});
}
WebChromeClient
WebView
預設是無法彈出 alert()
的,需要設定 WebChromeClient
mWebView.setWebChromeClient(new WebChromeClient());
todo
更多內容補充中 …
相關推薦
Android WebView詳解之檔案下載
1、佈局檔案activity_main.xml:線性佈局,TextView顯示頁面標題,WebView顯示頁面。 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
(轉)最全面的Android Webview詳解
原地址:http://blog.csdn.net/carson_ho/article/details/52693322 前言 現在很多App裡都內建了Web網頁(Hyprid App),比如說很多電商平臺,淘寶、京東、聚划算等等,如下圖 那麼這種該如何實現呢
Android WebView 詳解
本文記錄 Android 中 WebView 控制元件的相關使用,不斷完善中…主要包括:基本屬性的配置 WebView 快取相關內容 Java 與 Js 的互動 WebView 開啟本地應用(支付寶等) 載入網路連結,本地 sd 卡路徑,assert 目錄路徑的
android WebView詳解,常見漏洞詳解和安全原始碼(上)
這篇部落格主要來介紹 WebView 的相關使用方法,常見的幾個漏洞,開發中可能遇到的坑和最後解決相應漏洞的原始碼,以及針對該原始碼的解析。 由於部落格內容長度,這次將分為上下兩篇,上篇詳解 WebView 的使用,下篇講述 WebView 的漏洞和
Android:最全面的 Webview 詳解
前言 現在很多App裡都內建了Web網頁(Hyprid App),比如說很多電商平臺,淘寶、京東、聚划算等等,如下圖 那麼這種該如何實現呢?其實這是Android裡一個叫WebView的元件實現的。今天我將全面介紹WebView的常用用法。
Android開發:最全面、最易懂的Webview詳解
現在很多App裡都內建了Web網頁(Hyprid App),比如說很多電商平臺,淘寶、京東、聚划算等等,如下圖 京東首頁.jpg 那麼這種該如何實現呢?其實這是Android裡一個叫WebView的元件實現的。今天我將全面介紹WebView的常用用法。 目錄 文章目錄 1. 簡介
webView 與 Android互動詳解
具體原理: Android通過 WebViewClient 的回撥方法shouldOverrideUrlLoading ()攔截 url解析該 url 的協議如果檢測到是預先約定好的協議,就呼叫相應方法 即JS需要呼叫Android的方法 具體使用: 步驟1:在JS約定所需要的Url協議
WebView詳解及使用說明;(android外殼專案總結版)
最近做了一個關於webview寫安卓的殼,套HTML5的應用,雖然整個寫下來後,到了目前的進度,程式碼量不多,共有1000多行,但是整個殼的設計思想和實現思路還是當初查了很久的。所以寫下來,以備後續檢視和分享。 這個webview的殼目前實現的功能我將從三方面說明並總結。
WebView詳解與簡單Android與H5互調
為什麼要學習Android與H5互調? 微信,QQ空間等大量軟體都內嵌了H5,不得不說是一種趨勢。Android與H5互調可以讓我們的實現混合開發,至於混合開發就是在一個App中內嵌一個輕量級的瀏覽器,一部分原生的功能改為Html 5來開發。 優勢:使用H5實現的功能能夠在不升級App的情況下動態更
WebView詳解與簡單實現Android與H5互調
本篇文章已授權微信公眾號 guolin_blog (郭霖)獨家釋出 為什麼要學習Android與H5互調? 微信,QQ空間等大量軟體都內嵌了H5,不得不說是一種趨勢。Android與H5互調可以讓我們的實現混合開發,至於混合開發就是在一個App中內嵌
android -------- WIFI 詳解
mov 取ip地址 fico alt b- else if 無線網 pan PC 今天簡單的來聊一下安卓開發中的Wifi,一些常用的基礎,主要分為兩部分: 1:WiFi的信息 2:WiFi的搜索和連接 現在app大多都需要從網絡上獲得數據。所以訪問網絡是在
Android Permission詳解
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android ViewModel詳解
1. ViewModel概述 2. 實現一個ViewModel 3. ViewModel的生命週期 4. 在fragments之間共享資料 5. ViewModel替換Loaders 6. 附加資源 1.
Android LiveData詳解
官方文件翻譯 1.LiveData概述 1.1 使用LiveData的優點 1.2 使用LiveData物件 1.2.1 建立LiveData物件 1.2.2 觀察LiveData物件
Android Lifecycle詳解(一)
官方文件翻譯 使用生命週期感知元件處理生命週期 Lifecycle Event State LifecycleOwner 實現一個自定義的LifecycleOwner 生命週期感
Android Animation 詳解
關於動畫的實現,Android提供了Animation,在Android SDK介紹了2種Animation模式: 1. Tween Animation:通過對場景裡的物件不斷做影象變換(平移、縮放、旋轉)產生動畫效果,即是一種漸變動畫; 2. Frame Animation:
Android開發詳解之onTouch和onClick詳解
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android UI詳解之顏色資源的使用
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android開發--詳解ContentProvider/Cursor的使用
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android Activity 詳解
生命週期 如上圖所示,Activity生命週期很簡單共七個生命週期函式,oncreate(),onrestart(),onstart(),onresume(),onpause(),onstop(),ondestroy(); 下面舉兩個例子來說明Activity生命週期函式呼叫關係。