WebView极简用法

关键类

  • WebView
  • WebSettings
  • WebViewClient
  • WebChromeClient

WebView基本用法:

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

如果加载的是网络页面需要申请网络权限:


补充

  • 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文档如下:




    WebView Test
    
    
    


send email

call

send message

在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极简用法)