最近工作中,基本一直在用WebView,今天就把它整理下:
1、WebView簡介
WebView組件是Android提供用於顯示網頁信息,它內置了WebKit引擎,WebKit是一個開源的瀏覽器引擎,Chrome瀏覽器也是基於它,所以我們可以把WebView當做一個輕量級的瀏覽器使用。
在使用WebView前,先需要添加權限:
<uses-permission android:name="android.permission.INTERNET"/>
private WebView webview;
webview = (WebView) findViewById(R.id.webview);
2、使用WebView加載網頁
//加載網頁 webView.loadUrl("http://www.baidu.com"); //加載本地網頁,這里的格式是固定的,文件位置assets目錄下 webView.loadUrl(file:///android_asset/XXX.html); //使用loadData方法來加載html數據 //loadData需要三個參數:HTML TAG,MIME類型(text/html),網頁編碼方式(utf-8) webView.loadData(content,"text/html","UTF-8");
WebView狀態
//激活WebView為活躍狀態,能正常執行網頁的響應 webView.onResume() ; //當頁面被失去焦點被切換到后台不可見狀態,需要執行onPause //通過onPause動作通知內核暫停所有的動作,比如DOM的解析、plugin的執行、JavaScript執行。 webView.onPause(); //當應用程序(存在webview)被切換到后台時,這個方法不僅僅針對當前的webview而是全局的全應用程序的webview //它會暫停所有webview的layout,parsing,javascripttimer。降低CPU功耗。 webView.pauseTimers() //恢復pauseTimers狀態 webView.resumeTimers(); //銷毀Webview //在關閉了Activity時,如果Webview的音樂或視頻,還在播放。就必須銷毀Webview //但是注意:webview調用destory時,webview仍綁定在Activity上 //這是由於自定義webview構建時傳入了該Activity的context對象 //因此需要先從父容器中移除webview,然后再銷毀webview: rootLayout.removeView(webView); webView.destroy();
1.直接打開瀏覽器使用
Uri uri = Uri.parse("http://baidu.com");
Intent inten - new Intent(Intent.ACTION_VIEW, uri); startActivity(intent);
2.打開網頁時不調用系統瀏覽器,而是在本WebView中顯示
mWebView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } });
myWebView.setWebViewClient(new 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); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { //返回值是true的時候WebView打開,為false則系統瀏覽器或第三方瀏覽器打開。如果要下載頁面中的游戲或者繼續點擊網頁中的鏈接進入下一個網頁的話,重寫此方法下,不然就會跳到手機自帶的瀏覽器了,而不繼續在你這個webview里面展現了 return true; } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { //想在收到錯誤信息的時候,執行一些操作,走此方法 } });
3.返回鍵,返回上一次瀏覽的界面(不是退出程序)
還有一點很重要,要想進入通過webview瀏覽網頁,而且點返回鍵是想在webview中返回,而不是直接退出程序,那么就得重寫onKeyDown方法。
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && webView.canFoBack()) { // goBack()表示返回WebView的上一頁面 webView.goBack(); //退出全屏 quitFullScreen(); return true; } else { //結束當前頁 return super.onKeyDown(keyCode, event); } }
4.頁面縮放
設置自適應手機屏幕,兩者合用
webView.getSettings().setUseWideViewPort(true);//將圖片調整到適合webView的大小 webView.getSettings().setLoadWithOverviewMode(true);//縮放至屏幕大小
縮放操作
webSettings.setSupportZoom(true); //支持縮放,默認為true。是下面那個的前提。 webSettings.setBuiltInZoomControls(true); //設置內置的縮放控件。若為false,則該WebView不可縮放 webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件
比例縮放
webView.setInitialScale(50);
webView = (WebView) findViewById(R.id.webView_notification); // WebSettings webSettings = webView.getSettings(); webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);//設置js可以直接打開窗口,如window.open(),默認為false webView.getSettings().setJavaScriptEnabled(true);//是否允許執行js,默認為false。設置true時,會提醒可能造成XSS漏洞 webView.getSettings().setSupportZoom(true);//是否可以縮放,默認true webView.getSettings().setBuiltInZoomControls(true); webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.CLOSE); webView.getSettings().setUseWideViewPort(true);//設置此屬性,可任意比例縮放。大視圖模式 webView.getSettings().setLoadWithOverviewMode(true);//和setUseWideViewPort(true)一起解決網頁自適應問題 webView.getSettings().setAppCacheEnabled(true);//是否使用緩存 webView.getSettings().setDomStorageEnabled(true);//DOM Storage webView.getSettings().setUserAgentString("User-Agent:MicroMessenger");//設置用戶代理 webView.setWebChromeClient(mChromeClient); webView.setWebViewClient(mWebViewClient);
WebSettings webSettings = mWebView .getSettings(); //支持獲取手勢焦點,輸入用戶名、密碼或其他 webview.requestFocusFromTouch(); webSettings.setJavaScriptEnabled(true); //支持js webSettings.setPluginsEnabled(true); //支持插件 webSettings.setRenderPriority(RenderPriority.HIGH); //提高渲染的優先級 設置自適應屏幕,兩者合用 setUseWideViewPort(true); //將圖片調整到適合webview的大小 setLoadWithOverviewMode(true); // 縮放至屏幕的大小 setSupportZoom(true); //支持縮放,默認為true。是下面那個的前提。 setBuiltInZoomControls(true); //設置內置的縮放控件。 //若上面是false,則該WebView不可縮放,這個不管設置什么都不能縮放。 setTextZoom(2);//設置文本的縮放倍數,默認為 100 setDisplayZoomControls(false); //隱藏原生的縮放控件 setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支持內容重新布局 supportMultipleWindows(); //多窗口 setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉webview中緩存 setAllowFileAccess(true); //設置可以訪問文件 setNeedInitialFocus(true); //當webview調用requestFocus時為webview設置節點 setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口 setLoadsImagesAutomatically(true); //支持自動加載圖片 setDefaultTextEncodingName("utf-8");//設置編碼格式 setStandardFontFamily("");//設置 WebView 的字體,默認字體為 "sans-serif" setDefaultFontSize(20);//設置 WebView 字體的大小,默認大小為 16 setMinimumFontSize(12);//設置 WebView 支持的最小字體大小,默認為 8
關於緩存
緩存模式:
LOAD_CACHE_ONLY: 不使用網絡,只讀取本地緩存數據
LOAD_DEFAULT: (默認)根據cache-control決定是否從網絡上取數據。
LOAD_NO_CACHE: 不使用緩存,只從網絡獲取數據.
LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用緩存中的數據。
if (NetStatusUtil.isConnected(getApplicationContext())) { webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根據cache-control決定是否從網絡上取數據。 } else { webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//沒網,則從本地獲取,即離線加載 } webSettings.setDomStorageEnabled(true); // 開啟 DOM storage API 功能 webSettings.setDatabaseEnabled(true); //開啟 database storage API 功能 webSettings.setAppCacheEnabled(true);//開啟 Application Caches 功能 String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME; webSettings.setAppCachePath(cacheDirPath); //設置 Application Caches 緩存目錄
注意: 每個 Application 只調用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize()
Android5.0 WebView中Http和Https混合問題
在Android 5.0上 Webview 默認不允許加載 Http 與 Https 混合內容:
解決辦法:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
參數類型說明:
MIXED_CONTENT_ALWAYS_ALLOW:允許從任何來源加載內容,即使起源是不安全的;
MIXED_CONTENT_NEVER_ALLOW:不允許Https加載Http的內容,即不允許從安全的起源去加載一個不安全的資源;
MIXED_CONTENT_COMPATIBILITY_MODE:當涉及到混合式內容時,WebView 會嘗試去兼容最新Web瀏覽器的風格。
在5.0以下 Android 默認是 全允許,
但是到了5.0以上,就是不允許,實際情況下很我們很難確定所有的網頁都是https的,所以就需要這一步的操作。
示例:顯示“www.baidu.com”、獲取其標題、提示加載開始和結束和獲取加載進度。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.carson_ho.webview_demo.MainActivity"> <!-- 獲取網站的標題--> <TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> <!--開始加載提示--> <TextView android:id="@+id/text_beginLoading" android:layout_below="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> <!--獲取加載進度--> <TextView android:layout_below="@+id/text_beginLoading" android:id="@+id/text_Loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> <!--結束加載提示--> <TextView android:layout_below="@+id/text_Loading" android:id="@+id/text_endLoading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/> <!--顯示網頁區域--> <WebView android:id="@+id/webView1" android:layout_below="@+id/text_endLoading" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginTop="10dp" /> </RelativeLayout>
public class MainActivity extends AppCompatActivity { WebView mWebview; WebSettings mWebSettings; TextView beginLoading,endLoading,loading,mtitle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mWebview = (WebView) findViewById(R.id.webView1); beginLoading = (TextView) findViewById(R.id.text_beginLoading); endLoading = (TextView) findViewById(R.id.text_endLoading); loading = (TextView) findViewById(R.id.text_Loading); mtitle = (TextView) findViewById(R.id.title); mWebSettings = mWebview.getSettings(); mWebview.loadUrl("http://www.baidu.com/"); //設置不用系統瀏覽器打開,直接顯示在當前Webview mWebview.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } }); //設置WebChromeClient類 mWebview.setWebChromeClient(new WebChromeClient() { //獲取網站標題 @Override public void onReceivedTitle(WebView view, String title) { System.out.println("標題在這里"); mtitle.setText(title); } //獲取加載進度 @Override public void onProgressChanged(WebView view, int newProgress) { if (newProgress < 100) { String progress = newProgress + "%"; loading.setText(progress); } else if (newProgress == 100) { String progress = newProgress + "%"; loading.setText(progress); } } }); //設置WebViewClient類 mWebview.setWebViewClient(new WebViewClient() { //設置加載前的函數 @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { System.out.println("開始加載了"); beginLoading.setText("開始加載了"); } //設置結束加載函數 @Override public void onPageFinished(WebView view, String url) { endLoading.setText("結束加載了"); } }); } //點擊返回上一頁面而不是退出瀏覽器 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && mWebview.canGoBack()) { mWebview.goBack(); return true; } return super.onKeyDown(keyCode, event); } //銷毀Webview @Override protected void onDestroy() { if (mWebview != null) { mWebview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); mWebview.clearHistory(); ((ViewGroup) mWebview.getParent()).removeView(mWebview); mWebview.destroy(); mWebview = null; } super.onDestroy(); } }
參考:
http://www.jianshu.com/p/3fcf8ba18d7f?utm_source=desktop&utm_medium=timeline
http://blog.csdn.net/carson_ho/article/details/52693322