安卓APP承載網頁(WebView)- 用例程解析到位

安卓APP自身如何打開網頁,如何製作一個簡單的瀏覽器,WebView在其中將是一個重要的角色。WebView是一個基於WebKit引擎、展現Web頁面的控件。

Webview 是一個基於webkit引擎,可以解析DOM 元素,展示html頁面的控件,它和瀏覽器展示頁面的原理是相同的,所以可以把它當做瀏覽器看待。(chrome瀏覽器也是基於webkit引擎開發的,Mozilla瀏覽器是基於Gecko引擎開發的)

簡而言之,WebView可以實現安卓APP中承載網頁

 

手機瀏覽器:

國內手機的自帶瀏覽器不是chrome,主要是版權的原因,自帶的瀏覽器都是手機廠商基於國內主流的幾大瀏覽器自己定製,然後發佈在自己手機系統版本中.不過國內幾大瀏覽器廠商如QQ瀏覽器,UC瀏覽器、都是基於webkit引擎的,iphone的自帶瀏覽器是Safari,Safari瀏覽器的內核是webkit

 

使用WebView的好處:

  1. 使用內核都是webkit,所以APP中網頁展示的效果與主流瀏覽器差別無幾
  2. 這是一個BS架構即瀏覽器和服務器的,所以在某些要經常改變的界面嵌入WebView,可以方便隨時在後臺修改其內容

加載一個網頁的方法

加載服務器的網頁

//獲取到webview控件
WebView webv=findViewById(R.id.mywebview);
//加載網頁
webv.loadUrl("https://www.cnblogs.com/dongxiaodong/");

加載資源文件(assets目錄)的網頁

assets目錄是Android的一種特殊目錄,用於放置APP所需的固定文件,且該文件被打包到APK中時,不會被編碼到二進制文件。

//獲取到webview控件
WebView webv=findViewById(R.id.mywebview);
//加載網頁
webv.loadUrl("file:///android_asset/androidt.html");

網頁加載時附加網頁代碼

baseUrl表示基礎的網頁

data表示要加載的內容

mimeType表示加載網頁的類型

encoding表示編碼格式

historyUrl表示可用歷史記錄,可以爲null值

webv.loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl))

網頁瀏覽器的基礎屬性

canGoBack()   是否可以後退

canGoForward() 是否可以前進

canGoBackOrForward(int step) 是否可以前進或者後退多少步,正數爲前進,負數爲後退

goBack() 後退

goBack() 前進

goBackOrForward(int step)前進或者後退多少步,正數爲前進,負數爲後退

reload() 重新加載或刷新界面

stopLoading() 停止加載

實現:

 1 //後退函數實現
 2 public void But_back(View v){
 3     //查詢是否可以返回上一級
 4     boolean canx=webv.canGoBack();
 5     //返回上一級
 6     if(canx) webv.goBack();
 7     //不可返回
 8     else  Toast.makeText(MainActivity.this,"已經到達底端",Toast.LENGTH_SHORT).show();
 9 }
10 //前進函數實現
11 public void But_forward(View v){
12     boolean canx=webv.canGoForward();
13     //返回上一級
14     //查詢是否可以返回上一級
15     if(canx) webv.goForward();
16         //不可返回
17     else  Toast.makeText(MainActivity.this,"已經到達頂端",Toast.LENGTH_SHORT).show();
18 }
19 //刷新頁面
20 public void But_reload(View v){
21     webv.reload();
22 }
23 //停止界面加載
24 public void But_stop(View v){
25     webv.stopLoading();
26 }

WebView配置類(WebSettings)

 1 WebSettings webSettings = webView.getSettings();
 2     //如果訪問的頁面中要與Javascript交互,則webview必須設置支持Javascript
 3     webSettings.setJavaScriptEnabled(true);
 4 
 5     //設置自適應屏幕,兩者合用
 6     webSettings.setUseWideViewPort(true); //將圖片調整到適合webview的大小
 7     webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小
 8 
 9     webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持內容重新佈局
10 
11     //縮放操作
12     webSettings.setSupportZoom(true); //支持縮放,默認爲true。是下面那個的前提。
13     webSettings.setBuiltInZoomControls(true); //設置內置的縮放控件。若爲false,則該WebView不可縮放
14     webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件
15     webSettings.setTextZoom(2);//設置文本的縮放倍數,默認爲 100
16 
17     webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);  //提高渲染的優先級
18 
19     webSettings.setStandardFontFamily("");//設置 WebView 的字體,默認字體爲 "sans-serif"
20     webSettings.setDefaultFontSize(20);//設置 WebView 字體的大小,默認大小爲 16
21     webSettings.setMinimumFontSize(12);//設置 WebView 支持的最小字體大小,默認爲 8
22 
23     // 5.1以上默認禁止了https和http混用,以下方式是開啓
24     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
25         webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
26     }
27 
28     //其他操作
29     webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉webview中緩存
30     webSettings.setAllowFileAccess(true); //設置可以訪問文件
31     webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口
32     webSettings.setLoadsImagesAutomatically(true); //支持自動加載圖片
33     webSettings.setDefaultTextEncodingName("utf-8");//設置編碼格式
34     webSettings.setGeolocationEnabled(true);//允許網頁執行定位操作
35     webSettings.setUserAgentString("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0");//設置User-Agent
36 
37 
38     //不允許訪問本地文件(不影響assets和resources資源的加載)
39     webSettings.setAllowFileAccess(false);
40     webSettings.setAllowFileAccessFromFileURLs(false);
41     webSettings.setAllowUniversalAccessFromFileURLs(false);

事件監聽

各種通知和請求事件(WebViewClient)

onPageStarted()   頁面加載時

onPageFinished():頁面加載完畢時調用。

shouldOverrideKeyEvent():重寫此方法才能處理瀏覽器中的按鍵事件。

shouldInterceptRequest():頁面每一次請求資源之前都會調用這個方法(非UI線程調用)。

onLoadResource():頁面加載資源時調用,每加載一個資源(比如圖片)就調用一次。

onReceivedError():加載頁面的服務器出現錯誤(比如404)時回調。

onReceivedSslError():重寫此方法可以讓webview處理https請求。

doUpdateVisitedHistory():更新歷史記錄。

onFormResubmission():應用程序重新請求網頁數據。

onReceivedHttpAuthRequest():獲取返回信息授權請求。

onScaleChanged():WebView發生縮放改變時調用。

onUnhandledKeyEvent():Key事件未被加載時調用。

 

輔助 WebView 處理補充問題(WebChromeClient)

onProgressChanged():獲得網頁的加載進度並顯示。

onReceivedTitle():獲得網頁的標題時回調。

onReceivedIcon():獲得網頁的圖標時回調。

onCreateWindow():打開新窗口時回調。

onCloseWindow():關閉窗口時回調。

onJsAlert():網頁彈出提示框時觸發此方法。

上例程

統一統一步驟:

第一步:

在AndroidManifest.xml下添加網絡訪問權限,如果需要外網訪問的情況下

<!--網絡權限-->
<uses-permission android:name="android.permission.INTERNET" />
<!--文件讀寫權限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

第二步:

在xml下添加WebView控件

<WebView
    android:layout_width="match_parent"
    android:id="@+id/mywebview"
    android:layout_height="match_parent" />

加載可服務器的網頁:

這裏將使用WebView打開 博客園 東小東 的博客首頁

 第三步:

編寫邏輯程序

 1 import androidx.appcompat.app.AppCompatActivity;
 2 import android.os.Bundle;
 3 import android.view.KeyEvent;
 4 import android.webkit.WebView;
 5 import android.webkit.WebViewClient;
 6 public class MainActivity extends AppCompatActivity {
 7     private WebView webv=null;
 8     @Override
 9     protected void onCreate(Bundle savedInstanceState) {
10         super.onCreate(savedInstanceState);
11         setContentView(R.layout.activity_main);
12         //獲取到webview控件
13         webv=findViewById(R.id.mywebview);
14         //設置訪問的URL,此條將會觸發系統調用瀏覽器打開,博客園東小東
15         webv.loadUrl("https://www.cnblogs.com/dongxiaodong/");
16         //通過下面的代碼阻止APP直接通過瀏覽器打開網頁
17         webv.setWebViewClient(new WebViewClient(){
18             @Override
19             public boolean shouldOverrideUrlLoading(WebView view, String url) {
20                 //使用WebView加載URL內容
21                 view.loadUrl(url);
22                 return  true;
23             }
24         });
25     }
26     //監聽程序的返回事件
27     public boolean onKeyDown(int keyCode, KeyEvent event) {
28         //如果按下返回鍵且網頁有歷史記錄,可以返回上一級
29         if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {
30             //返回上一級
31             webv.goBack();
32             return true;
33         }
34         //否則返回真實的按鍵信息給系統,系統將將退出程序
35         return super.onKeyDown(keyCode, event);
36     }
37 }

加載資源文件(assets目錄)的網頁

assets目錄是Android的一種特殊目錄,用於放置APP所需的固定文件,且該文件被打包到APK中時,不會被編碼到二進制文件。

  第三步:

編寫HTML代碼,保存到文件androidt.html

 1 <!doctype html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8">
 5 <title>這裏是網頁頭</title>
 6 </head>
 7 <body style="margin: 0 auto;text-align: center">
 8     <h1>我是網頁標題1</h1>
 9     <h3>(資源文件方法)</h3>
10     <button onClick="showA()" style="width: 100%;height: 100px;">點我彈框</button>
11 </body>
12     <script>
13         function showA(){
14             alert("彈框內容,完成");
15         }
16     </script>
17 </html>

第四步

創建assets目錄

右鍵【app】-【New】-【Folder】-【Assets Folder】-【finish】

第五步

將HTML文件拷貝到assets目錄下

第六步

 1 import androidx.appcompat.app.AppCompatActivity;
 2 import android.os.Bundle;
 3 import android.webkit.JsResult;
 4 import android.webkit.WebChromeClient;
 5 import android.webkit.WebSettings;
 6 import android.webkit.WebView;
 7 import android.webkit.WebViewClient;
 8 public class MainActivity extends AppCompatActivity {
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.activity_main);
13         //獲取到webview控件
14         WebView webv=findViewById(R.id.mywebview);
15 
16         WebSettings webSettings = webv.getSettings();
17         webSettings.setJavaScriptEnabled(true);//設置支持Javascript
18         webSettings.setJavaScriptCanOpenWindowsAutomatically(true);//允許js彈出窗口
19 
20         //訪問本地資源文件網頁
21         webv.loadUrl("file:///android_asset/androidt.html");
22 
23         //通過下面的代碼阻止APP直接通過瀏覽器打開網頁
24         webv.setWebViewClient(new WebViewClient(){
25             @Override
26             public boolean shouldOverrideUrlLoading(WebView view, String url) {
27                 //使用WebView加載URL內容
28                 view.loadUrl(url);
29                 return  true;
30             }
31         });
32         //如果要實習alert彈框,必須實現此監聽事件
33         webv.setWebChromeClient(new WebChromeClient() {
34             @Override
35             public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
36                 // TODO Auto-generated method stub
37                 return super.onJsAlert(view, url, message, result);
38             }
39         });
40     }
41 }

加載部分源代碼

直接寫一部分的HTML代碼,可以直接顯示在WebView上

 第三步:

編寫邏輯程序

 1 package com.example.myapplication;
 2 
 3 import androidx.appcompat.app.AppCompatActivity;
 4 import android.os.Bundle;
 5 import android.view.KeyEvent;
 6 import android.webkit.WebSettings;
 7 import android.webkit.WebView;
 8 import android.webkit.WebViewClient;
 9 public class MainActivity extends AppCompatActivity {
10     private WebView webv=null;
11     @Override
12     protected void onCreate(Bundle savedInstanceState) {
13         super.onCreate(savedInstanceState);
14         setContentView(R.layout.activity_main);
15         //獲取到webview控件
16         webv=findViewById(R.id.mywebview);
17         WebSettings webSettings = webv.getSettings();
18 
19         //將網頁界面縮放至手機屏幕大小
20         webSettings.setUseWideViewPort(true); //將圖片調整到適合webview的大小
21         webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小
22 
23         //設置支持縮放操作
24         webSettings.setSupportZoom(true); //支持縮放,默認爲true。是下面那個的前提。
25         webSettings.setBuiltInZoomControls(true); //設置內置的縮放控件。若爲false,則該WebView不可縮放
26         webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件
27 
28         //編輯網頁代碼
29         String myhtml="<h1 >東小東標題</h1>" +
30                       "<hr/>" +
31                       "<a href='https://www.cnblogs.com/dongxiaodong/'>去東小東博客園看看<a/>" +
32                       "<h3 >網頁顯示小標題</h3>" +
33                       "<img style=\"width: 100%;\" src=\"https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png\"/>";
34         //設置顯示
35         webv.loadDataWithBaseURL("",myhtml,"text/html", "utf-8",null);
36 
37         //通過下面的代碼阻止APP直接通過瀏覽器打開網頁
38         webv.setWebViewClient(new WebViewClient(){
39             @Override
40             public boolean shouldOverrideUrlLoading(WebView view, String url) {
41                 //使用WebView加載URL內容
42                 view.loadUrl(url);
43                 return  true;
44             }
45         });
46     }
47     //監聽程序的返回事件
48     public boolean onKeyDown(int keyCode, KeyEvent event) {
49         //如果按下返回鍵且網頁有歷史記錄,可以返回上一級
50         if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {
51             //返回上一級
52             webv.goBack();
53             return true;
54         }
55         //否則返回真實的按鍵信息給系統,系統將將退出程序
56         return super.onKeyDown(keyCode, event);
57     }
58 }

綜合案例

缺點:工程未實現網頁的音頻和視頻播放

實現功能:

l  標題顯示

l  網頁加載進度條顯示

l  後退、前進、刷新、停止加載四大常用功能適配

l  連接跳轉,在APP本地打開網頁

 

 

視圖源碼

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent"
 7     tools:context=".MainActivity">
 8     <LinearLayout
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent"
11         android:orientation="vertical">
12 
13      <TextView
14          android:layout_width="match_parent"
15          android:layout_height="wrap_content"
16          android:textSize="15dp"
17          android:id="@+id/show_text"
18          android:background="@color/colorPrimary"
19          android:text="標題顯示"/>
20     <ProgressBar
21         android:max="100"
22         android:progress="10"
23         android:id="@+id/show_progres"
24         style="?android:attr/progressBarStyleHorizontal"
25         android:background="@color/colorPrimary"
26         android:layout_width="match_parent"
27         android:layout_height="wrap_content"/>
28 
29     <WebView
30         android:layout_width="match_parent"
31         android:id="@+id/mywebview"
32         android:layout_height="match_parent" />
33     </LinearLayout>
34     <LinearLayout
35         android:layout_width="match_parent"
36         android:layout_height="wrap_content"
37         android:layout_gravity="bottom"
38         android:orientation="horizontal">
39 
40         <Button
41             android:layout_width="wrap_content"
42             android:layout_height="wrap_content"
43             android:layout_weight="1"
44             android:onClick="But_back"
45             android:text="後退"/>
46         <Button
47             android:layout_width="wrap_content"
48             android:layout_height="wrap_content"
49             android:onClick="But_forward"
50             android:layout_weight="1"
51             android:text="前進"/>
52         <Button
53             android:layout_width="wrap_content"
54             android:layout_height="wrap_content"
55             android:onClick="But_reload"
56             android:layout_weight="1"
57             android:text="刷新"/>
58         <Button
59             android:layout_width="wrap_content"
60             android:layout_height="wrap_content"
61             android:onClick="But_stop"
62             android:layout_weight="1"
63             android:text="停止"/>
64 
65 
66     </LinearLayout>
67 
68 </FrameLayout>

邏輯源碼

  1 import androidx.appcompat.app.AppCompatActivity;
  2 import android.os.Bundle;
  3 import android.view.KeyEvent;
  4 import android.view.View;
  5 import android.webkit.WebChromeClient;
  6 import android.webkit.WebSettings;
  7 import android.webkit.WebView;
  8 import android.webkit.WebViewClient;
  9 import android.widget.ProgressBar;
 10 import android.widget.TextView;
 11 import android.widget.Toast;
 12 
 13 public class MainActivity extends AppCompatActivity {
 14     private WebView webv=null;
 15     private TextView showtext=null;
 16     private ProgressBar showpro=null;
 17     @Override
 18     protected void onCreate(Bundle savedInstanceState) {
 19         super.onCreate(savedInstanceState);
 20         //隱藏狀態欄
 21         getSupportActionBar().hide();
 22         setContentView(R.layout.activity_main);
 23         //獲取到webview控件
 24         webv=findViewById(R.id.mywebview);
 25         showtext=findViewById(R.id.show_text);
 26         showpro=findViewById(R.id.show_progres);
 27 
 28         WebSettings webSettings = webv.getSettings();
 29 
 30        webSettings .setAllowFileAccess(true);
 31         //設置支持縮放操作
 32         webSettings.setSupportZoom(true); //支持縮放,默認爲true。是下面那個的前提。
 33         webSettings.setBuiltInZoomControls(true); //設置內置的縮放控件。若爲false,則該WebView不可縮放
 34         webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件
 35 
 36         //編輯網頁代碼
 37         String myhtml="<h1 >東小東標題</h1>" +
 38                 "<hr/>" +
 39                 "<h2><a href='https://www.cnblogs.com/dongxiaodong/'>去東小東博客園看看<a/></h2>" +
 40                 "<h3 >網頁顯示小標題</h3>" +
 41                 "<img style=\"width: 300px;\" src=\"https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png\"/>";
 42         //設置顯示
 43         webv.loadDataWithBaseURL("",myhtml,"text/html", "utf-8",null);
 44 
 45         //通過下面的代碼阻止APP直接通過瀏覽器打開網頁
 46         webv.setWebViewClient(new WebViewClient(){
 47             @Override
 48             public boolean shouldOverrideUrlLoading(WebView view, String url) {
 49                 //使用WebView加載URL內容
 50                 view.loadUrl(url);
 51                 return  true;
 52             }
 53         });
 54         webv.setWebChromeClient(new WebChromeClient() {
 55             @Override
 56             public void onReceivedTitle(WebView view, String title) {
 57                 //標題顯示
 58                 showtext.setText(title);
 59                 //Toast.makeText(MainActivity.this,title,Toast.LENGTH_SHORT).show();
 60             }
 61 
 62             @Override
 63             public void onProgressChanged(WebView view, int newProgress) {
 64                 super.onProgressChanged(view, newProgress);
 65                 //進度條顯示
 66                 showpro.setProgress(newProgress);
 67                 //Toast.makeText(MainActivity.this,newProgress+"",Toast.LENGTH_SHORT).show();
 68             }
 69         });
 70 
 71     }
 72     //監聽程序的返回事件
 73     public boolean onKeyDown(int keyCode, KeyEvent event) {
 74         //如果按下返回鍵且網頁有歷史記錄,可以返回上一級
 75         if ((keyCode == KeyEvent.KEYCODE_BACK) && webv.canGoBack()) {
 76             //返回上一級
 77             webv.goBack();
 78             return true;
 79         }
 80         //否則返回真實的按鍵信息給系統,系統將將退出程序
 81         return super.onKeyDown(keyCode, event);
 82     }
 83 
 84     //後退函數實現
 85     public void But_back(View v){
 86         //查詢是否可以返回上一級
 87         boolean canx=webv.canGoBack();
 88         //返回上一級
 89         if(canx) webv.goBack();
 90         //不可返回
 91         else  Toast.makeText(MainActivity.this,"已經到達底端",Toast.LENGTH_SHORT).show();
 92     }
 93     //前進函數實現
 94     public void But_forward(View v){
 95         boolean canx=webv.canGoForward();
 96         //返回上一級
 97         //查詢是否可以返回上一級
 98         if(canx) webv.goForward();
 99             //不可返回
100         else  Toast.makeText(MainActivity.this,"已經到達頂端",Toast.LENGTH_SHORT).show();
101     }
102     //刷新頁面
103     public void But_reload(View v){
104         webv.reload();
105     }
106     //停止界面加載
107     public void But_stop(View v){
108         webv.stopLoading();
109     }
110 }

參考:

https://blog.csdn.net/Jolting/article/details/81223904?utm_source=blogxgwz9

https://blog.csdn.net/weixin_40438421/article/details/85700109

https://www.jianshu.com/p/3e0136c9e748

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章