WebView極簡用法

關(guān)鍵類

  • WebView
  • WebSettings
  • WebViewClient
  • WebChromeClient

WebView基本用法:

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

如果加載的是網(wǎng)絡(luò)頁面需要申請網(wǎng)絡(luò)權(quán)限:

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

補(bǔ)充

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

配置WebView

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

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

當(dāng)我們通過WebView來加載了一個(gè)頁面時(shí),點(diǎn)擊頁面上的鏈接時(shí),會(huì)彈出一個(gè)對話框,讓我們選擇通過哪個(gè)瀏覽器來打開,如果我們希望直接在自己的WebView中打開,就可以通過如下方法實(shí)現(xiàn):

myWebView.setWebViewClient(new WebViewClient());  

WebView攔截資源請求

有時(shí)候我們不希望自己的WebView處理相關(guān)的請求,例如頁面中具有發(fā)郵件,打電話,發(fā)消息這類鏈接的時(shí)候,我們希望用戶點(diǎn)擊之后會(huì)啟動(dòng)第三方應(yīng)用,而不是我們自己的WebView處理,就可以通過如下方式實(shí)現(xiàn)。

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

<!DOCTYPE html>
<html>
<head>
    <title>WebView Test</title>
    <!--下面前兩個(gè)方法通過javascript調(diào)用WebView中的java代碼-->
    <!--第三個(gè)方法,就是簡單的javascript代碼,在網(wǎng)頁打開,會(huì)有一個(gè)警告對話框-->
    <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>
<!--兩個(gè)綁定點(diǎn)擊事件的按鈕-->
<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處理,會(huì)調(diào)用第三方應(yīng)用。

// 注意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);

補(bǔ)充

  • 當(dāng)我們想要屏蔽掉網(wǎng)頁的某些資源的時(shí)候,需要重寫WebViewClient的shouldIntercepterRequest()方法,而重寫shouldOverrideUrlLoading是沒有效果的。因?yàn)榫W(wǎng)頁的資源是在"IO"線程里加載的,而shouldOverrideUrlLoading運(yùn)行在主線程,只能攔截新的URL對象,也就是頁面需要重寫加載的時(shí)候,才會(huì)回調(diào)。而shouldIntercepterRequest方法運(yùn)行在IO線程里,可以對資源請求進(jìn)行攔截,并且可以返回其他的資源。
  • 禁止加載圖片
    webSettings.setLoadsImagesAutomatically(false)
  • 當(dāng)頁面載入錯(cuò)誤時(shí),可以重寫WebViewClientonReceivedError()方法。

JavaScript和WebView的交互

Jave調(diào)用Javascript

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

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

通過重載WebChromeClient調(diào)用

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

myWebView.setWebChromeClient(new WebChromeClient());

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

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

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調(diào)用java

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

首先我們創(chuàng)建一個(gè)類,如下:

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

    public WebAppInterface(Context c) {
        mContext = c;
    }
// 對應(yīng)html第一個(gè)方法
    @JavascriptInterface
    public void newActivity(){
        Intent intent = new Intent(mContext,JSActivity.class);
        mContext.startActivity(intent);
    }
// 對應(yīng)html中第二個(gè)方法
    @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添加這個(gè)js接口

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

之后就可以通過js調(diào)用上面設(shè)置的兩個(gè)方法了。詳細(xì)信息請參考上面的html文件。

WebView小拓展

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

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

WebView調(diào)試技巧

添加如下代碼

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容