WebView極簡用法

關鍵類

  • WebView
  • WebSettings
  • WebViewClient
  • WebChromeClient

WebView基本用法:

WebView myWebView = (WebView) findViewById(R.id.webview);
myWebView.loadUrl("http://www.example.com");

如果加載的是網絡頁面需要申請網絡權限:

<uses-permission android:name="android.permission.INTERNET" />

補充

  • WebView還有兩個方法,loadData(String data, String miniType,String edcoding)loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl).有時候loadData()只能加載‘data’,會導致其他協議的URL無法加載,當加載的URL不一定是‘data’時推薦用后一個方法。
    • mimeType: 數據類型,如:text/html.
    • encoding: 數據編碼方式 base64 或者 url encoding.
    • baseUrl: 指定頁面的根路徑.
  • URL統一資源定位符(uniform resource locator),URI統一資源標識符(uniform resource identifier )。URI包括URL。URL的一般語法scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]

配置WebView

配置WebView,需要先獲得一個WebSettings對象。WebSettings對象并不是通過new來獲得,而是在我們創建WebView的時候,就會獲得一個默認的WebSettings對象。這個WebSetting對象可以通過myWebView.getSettings()來獲得。

WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);

當我們通過WebView來加載了一個頁面時,點擊頁面上的鏈接時,會彈出一個對話框,讓我們選擇通過哪個瀏覽器來打開,如果我們希望直接在自己的WebView中打開,就可以通過如下方法實現:

myWebView.setWebViewClient(new WebViewClient());  

WebView攔截資源請求

有時候我們不希望自己的WebView處理相關的請求,例如頁面中具有發郵件,打電話,發消息這類鏈接的時候,我們希望用戶點擊之后會啟動第三方應用,而不是我們自己的WebView處理,就可以通過如下方式實現。

首先我將一個html文檔放在了main/assets目錄下,注意不是res/目錄下。模擬一個網頁。html文檔如下:

<!DOCTYPE html>
<html>
<head>
    <title>WebView Test</title>
    <!--下面前兩個方法通過javascript調用WebView中的java代碼-->
    <!--第三個方法,就是簡單的javascript代碼,在網頁打開,會有一個警告對話框-->
    <script type="text/javascript">
        var new_activity = function(){
            android.newActivity();
        }

        var send_notification = function(){
            android.sendNotification();
        }

         window.onload = function(){
            alert("alert from javascript");
        }
    </script>
</head>
<body>
<p><a href="mailto: study@163.com">send email</a></p>
<p><a href="tel: 12312312312">call</a></p>
<p><a href="sms: 10086">send message</a></p>
<!--兩個綁定點擊事件的按鈕-->
<button onclick="new_activity()">new activity</button>
<button onclick="send_notification()">send notification</button>
</body>
</html>

在java代碼中重寫WebViewClient的shouldOverrideUrlLoading(WebView view, String url)方法,該方法返回true,表示重寫了該方法,這次請求不由自己的WebView處理,會調用第三方應用。

// 注意url的寫法。
String url = "file:///android_asset/index_test.html";
myWebView.setWebViewClient(new WebViewClient(){
    @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
         Uri uri = Uri.parse(url);
         if ("mailto".equalsIgnoreCase(uri.getScheme())
              ||"tel".equalsIgnoreCase(uri.getScheme())
              ||"sms".equalsIgnoreCase(uri.getScheme())){
          //注意這里Intent Action的寫法。      
          Intent intent=new Intent(Intent.ACTION_VIEW, uri);
          startActivity( intent);
          return true;
          }
        return false;
      }
});
myWebView.loadUrl(url);

補充

  • 當我們想要屏蔽掉網頁的某些資源的時候,需要重寫WebViewClient的shouldIntercepterRequest()方法,而重寫shouldOverrideUrlLoading是沒有效果的。因為網頁的資源是在"IO"線程里加載的,而shouldOverrideUrlLoading運行在主線程,只能攔截新的URL對象,也就是頁面需要重寫加載的時候,才會回調。而shouldIntercepterRequest方法運行在IO線程里,可以對資源請求進行攔截,并且可以返回其他的資源。
  • 禁止加載圖片
    webSettings.setLoadsImagesAutomatically(false)
  • 當頁面載入錯誤時,可以重寫WebViewClientonReceivedError()方法。

JavaScript和WebView的交互

Jave調用Javascript

直接調用
myWebView.loadUrl("javascript:alert(java to javascript)");  

補充
也可以通過evaluateJavascript方法來處理帶有返回值的js方法。

通過重載WebChromeClient調用

注意上面的Html代碼,當頁面加載時會有一個彈出對話框。雖然已給WebView設置里setJavaScriptEnabled(true),但是WebView依然無法顯示對話框。通過如下方法就可使對話框顯示。

myWebView.setWebChromeClient(new WebChromeClient());

那么WebChromeClientWebViewClient有什么不同呢?前者主要負責輔助處理JS,與頁面內容交互。后者主要負責頁面加載過程中的事件通知。

如果你覺得這個彈窗實在太難看了,我們可以通過如下方法,重新自定義:

myWebView.setWebChromeClient(new WebChromeClient(){
    @Override
    public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
    Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();
    result.confirm();
    return true;
    }
});

Javascript調用java

主要是通過addJavascriptInterface(Object object,String name),向Javascript中注入對象和對象的名字。在api17以下會注入所有public方法,api17以上只會注入添加了@JavascriptInterface注釋的方法。

首先我們創建一個類,如下:

public class WebAppInterface {
    private Context mContext;
    private final static int NOTIFICATION_ID = 1;

    public WebAppInterface(Context c) {
        mContext = c;
    }
// 對應html第一個方法
    @JavascriptInterface
    public void newActivity(){
        Intent intent = new Intent(mContext,JSActivity.class);
        mContext.startActivity(intent);
    }
// 對應html中第二個方法
    @JavascriptInterface
    public void sendNotification(){
        Notification notification = new NotificationCompat.Builder(mContext)
                .setContentTitle("hello")
                .setContentText("this notification is sent by js")
                .setSmallIcon(R.drawable.notification_icon)
                .setAutoCancel(true)
                .setDefaults(Notification.DEFAULT_ALL)
                .build();
        NotificationManager manager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(NOTIFICATION_ID,notification);
    }
}

然后為WebView添加這個js接口

myWebView.addJavascriptInterface(new WebAppInterface(mContext),"android");  

之后就可以通過js調用上面設置的兩個方法了。詳細信息請參考上面的html文件。

WebView小拓展

如果我們不希望用戶點擊了WebView中的鏈接跳轉之后,按下返回鍵直接退出應用,可以在Activity中重寫onBackPress方法

@Override
    public void onBackPressed() {
        if (myWebView.canGoBack()){
            myWebView.goBack();
        }else {
            super.onBackPressed();
        }
    }     

WebView調試技巧

添加如下代碼

if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.KITKAT && BuildConfig.DEBUG){
   myWebView.setWebContentsDebuggingEnabled(true);
}

在chrome瀏覽器中輸入chrome//inspect/#devices.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    小莊bb閱讀 3,536評論 3 25
  • Tips 由于WebView的用法實在太多,如果您只是想查詢某個功能的使用——建議Ctrl+F(Commad+F)...
    BugDev閱讀 7,782評論 11 109
  • WebView·開車指南 目錄 WebView簡介 WebView基本使用 WebView常用方法 WebSett...
    南城的人閱讀 4,779評論 0 19
  • WebView·開車指南 2016-08-31BugDev 北京市東城區首席Bug布道師開山之作,一整月交通事故血...
    53c021c38a1d閱讀 848評論 0 1
  • 我有一個朋友,本來打算在一橋江邊的某小區買房子,過去看了樓盤。架不住推銷員口吐蓮花,先給人家交了5萬定金。后來,他...
    Rabbit622閱讀 417評論 7 2