Android WebView的简单使用和注意事项。

最近项目里用到webview来呈现一个视频网站的内容。正好趁此机会研究一下WebView的使用。

 

1. WebSettings

  用于管理WebView状态的设置。

        //Webview的设置接口都在WebSettings类里面。
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);//支持javascript
        webSettings.setUseWideViewPort(true); //设置使web页自适应屏幕
        webSettings.setLoadWithOverviewMode(true);////缩放至屏幕的大小
        webSettings.setSupportZoom(false); //设置支持缩放
        webSettings.setBuiltInZoomControls(false); //在网页上添加放大缩小的控件
        webSettings.setDisplayZoomControls(false); //在网页上显示放大缩小的控件
        webSettings.setLoadsImagesAutomatically(true); //设置自动加载图片

        webSettings.setBlockNetworkImage(true);    //设置网页在加载的时候暂时不加载网络图片
        webSettings.setAppCachePath("");   //设置缓存路径
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);   //设置缓存模式

        //页面需要访问本地资源图片的时候,需要设置下面三个方法。
        webSettings.setAllowUniversalAccessFromFileURLs(true);//设置是否允许通过 file url 加载的 Javascript 可以访问其他的源(包括http、https等源)
        webSettings.setAllowFileAccess(true); //设置可以访问file:///类型文件
        webSettings.setAllowFileAccessFromFileURLs(false);  //设置是否允许通过 file url 加载的 Js代码读取其他的本地文件。安全问题。

        //可以让WebView访问ContentPrivider存储的内容。 默认true
        webSettings.setAllowContentAccess(boolean allow);

2. loadUrl(), loadData()和loadDataWithBaseUrl()

  •    loadUrl(), 加载固定url。 可以加载网络url,也可以加载本地已经缓存的html文件。
mWebview.loadUrl("file:///android_asset/index.html");
mWebview.loadUrl("https://www.csdn.net");
  •   loadData(), 加载html字符串。html字符串里面不能出现英文字符:'#', '%', '\' , '?' 这四个字符,如果有的话可以用 %23, %25, %27, %3f来替换。这里就遇到坑了,当加载本地html字符串时,由于包含本地资源图片,图片路径是“file:///android_asset/error.png”, 有斜杠“\”, 所以图片怎么也加载不出来。用loadDataWithBaseUrl()就好了。所以loadData()不太使用。
mWebView.loadData(htmlData, "text/html", "UTF-8");//API提供的标准用法,无法解决乱码问题
mWebView.loadData(htmlData, "text/html; charset=UTF-8", null);//这种写法可以解决乱码问题

webView.loadData(URLEncoder.encode(htmlData, "utf-8"), "text/html",  "utf-8");//解决四个特殊字符问题
  •   loadDataWithBaseUrl(), 也是加载html字符串,但是没有loadData()的缺点。自然用的最多。
mWebView.loadDataWithBaseURL(null, mHtmlString, "text/html", "UTF-8", null);

3. WebViewClient

WebViewClient是WebView的callback方法,用来处理加载时的各种通知与事件,比如WebView中页面加载的开始、结束,以及错误等等。列举几个简单,必用的API。其他接口可能需要对html/js网页开发技术比较了解才能理解得了。由于本人不熟悉js,所以就不再列举其他方法了。

  •  shouldOverrideUrlLoading(WebView view, WebResourceRequest request)

用来防止跳转出webview的,此方法在POST请求时不会调用。当返回false的时候就会把打开url的任务交给系统,返回true的时候就会用当前的webview来打开该url。说是每一次调用都会到这里来,但是不一定的,主url一样,只是参数变了,就不会进来。 另外,很多网站跳转的时候,URL不是以http或者https开头的, 这样会导致schema错误,这个方法也处理这个问题。

  • onPageStarted(WebView view, String url, Bitmap favicon)

这个方法是在开始加载网页的时候开始调用的。大多数一调用loadURL()就开始调用onPageStart()了,但是注意,如果是那种404的网站,facebook等,会白屏很久,最后连接超时退出时才会依次调用onPageStart()-->onPageFinished()-->onReceivedError().也就是说这个方法是在socket连接上以后,从inputstream里开始读数据时才调用。 

Bitmap favicon, 是网站的小图标,需要事先getFavicon()下载过来放到本地。如果这个favicon已经存储在本地数据库中,则会返回这个网页的favicon,否则返回为null。

  • onPageFinished(WebView view, String url)

页面加载(包括重定向)结束后或者加载错误后都会调用。

  • onReceivedError(WebView view, int errorCode, String description, String failingUrl) 

当网络加载出现异常时就会回调这个方法。下面是所有的errror code。加载错误不仅仅是网络的原因,还是比如不以http/https开头的schema原因。

    public static final int ERROR_AUTHENTICATION = -4;
    public static final int ERROR_BAD_URL = -12;
    public static final int ERROR_CONNECT = -6;
    public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
    public static final int ERROR_FILE = -13;
    public static final int ERROR_FILE_NOT_FOUND = -14;
    public static final int ERROR_HOST_LOOKUP = -2;
    public static final int ERROR_IO = -7;
    public static final int ERROR_PROXY_AUTHENTICATION = -5;
    public static final int ERROR_REDIRECT_LOOP = -9;
    public static final int ERROR_TIMEOUT = -8;
    public static final int ERROR_TOO_MANY_REQUESTS = -15;
    public static final int ERROR_UNKNOWN = -1;
    public static final int ERROR_UNSAFE_RESOURCE = -16;
    public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
    public static final int ERROR_UNSUPPORTED_SCHEME = -10;
    public static final int SAFE_BROWSING_THREAT_MALWARE = 1;
    public static final int SAFE_BROWSING_THREAT_PHISHING = 2;
    public static final int SAFE_BROWSING_THREAT_UNKNOWN = 0;
    public static final int SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE = 3;
        mWebView.setWebViewClient(new WebViewClient() {
//防止跳转出webview的. 另外很多网站跳转时候URL不是以http或者https开头的, 这样会导致schema错误,这个方法也处理这个问题。
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                String url = request.getUrl().toString();

                try {
                    if (url.startsWith("http:") || url.startsWith("https:")) {
                        view.loadUrl(url);
                    } else {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                    }
                } catch (Exception e) {
                    return false;
                }
                return true;
            }


            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                showProgress(false);
            }

            @Override
            public void onPageFinished(WebView view, String url) {

            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                //also will be schema error, not network error.
                if (errorCode == WebViewClient.ERROR_TIMEOUT
                        || errorCode == WebViewClient.ERROR_HOST_LOOKUP
                        || errorCode == WebViewClient.ERROR_CONNECT
                        || errorCode == WebViewClient.ERROR_PROXY_AUTHENTICATION) {
                    if (TextUtils.isEmpty(mHtml)) {
                        mHtml = Constants.WEB_VIEW_LOAD_ERROR_PAGE.replace("[title]", getString(R.string.Network_Problem)).replace("[body]", getString(R.string.check_network_problem));
                    }

                    mWebView.loadDataWithBaseURL(null, mHtml, "text/html", "UTF-8", null);
                }
            }
        });
  • shouldInterceptRequest(WebView view, String url)

所有资源请求(包括css,js, image)出去之前,都会回调这个方法,所以可以做一些判断和拦截替换。这是非UI线程,替换的资源最好预先加载到内存,不然会出现错误。

接下的方法只是记录一下用处,笔者在项目中没有实际使用过,而且也不常用。不属于简单使用范畴。

  • onReceivedLoginRequest(WebView view, String realm, String account, String args) 

通知应用程序有个自动登录的帐号过程

  • onScaleChanged(WebView view, float oldScale, float newScale)

通知应用程序webview 要被scale。应用程序可以处理改事件,比如调整适配屏幕。应该要和webSettings.setSupportZoom(true)联用。

  • shouldOverrideKeyEvent(WebView view, KeyEvent event)

提供应用程序同步一个处理按键事件的机会,菜单快捷键需要被过滤掉。如果返回true,webview不处理该事件,如果返回false,webview会一直处理这个事件,因此在view 链上没有一个父类可以响应到这个事件。默认行为是return false;

  • onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)

通知应用程序WebView接收到了一个Http auth的请求,应用程序可以使用supplied 设置webview的响应请求。默认行为是cancel 本次请求。

  • onReceivedSslError(WebView view, SslErrorHandler handler,SslError error)

当网页加载资源过程中发现SSL错误会调用此方法。我们应用程序必须做出响应,是取消请求handler.cancel(),还是继续请求handler. proceed();内核的默认行为是handler.cancel();

  • onFormResubmission(WebView view, Message dontResend,Message resend)

如果浏览器需要重新发送POST请求,可以通过这个时机来处理。默认是不重新发送数据。

  • doUpdateVisitedHistory(WebView view, String url, boolean isReload)

通知应用程序可以将当前的url存储在数据库中,意味着当前的访问url已经生效并被记录在内核当中。这个函数在网页加载过程中只会被调用一次。注意网页前进后退并不会回调这个函数。

  • onPageCommitVisible(WebView view, String url)

HTTP的body标签加载前调用,仅在主frame调用。

  • onReceivedHttpError( WebView view, WebResourceRequest request, WebResourceResponse errorResponse)

通知应用程序在加载资源时从服务器接收到HTTP错误。HTTP错误的状态代码>=400。此回调将调用任何资源(IFRAME、图像等),而不只是针对主页。因此,建议在该回调中执行最小所需的工作。注意,服务器响应的内容不能在errorCode参数中提供。

  • onRenderProcessGone(WebView view, RenderProcessGoneDetail detail)

通知宿主应用程序已经退出给定的WebVIEW的渲染过程。 return true如果宿主应用程序处理进程已退出的情况,否则,如果渲染过程崩溃,应用程序将崩溃,或者如果渲染过程被系统杀死则会被杀死。

  • onReceivedClientCertRequest(WebView view, ClientCertRequest request)

通知主机应用程序处理SSL客户端证书请求。如果需要,主机应用程序负责显示UI并提供密钥。有三种方式来响应:proceed(), cancel()或ignore()。WebVIEW将调用响应存储在内存中(对于应用程序的生命周期)如果proceed() 或 cancel()被调用并且个对同样的主机:端口不会再次调用onReceivedClientCertRequest()。如果调用ignore(),WebVIEW不会存储响应。要注意多层chromium网络栈可能会缓存相应,所以最好的行为就是忽略(ignore)。这个方法在UI线程上被调用。在回调期间,连接被挂起。

4. WebChromeClient 

WebChromeClient主要辅助WebView处理Javascript的交互以及浏览器层面的事件

  • onProgressChanged(WebView view, int newProgress)

通知主程序当前加载页面进度。

  • onPermissionRequest(PermissionRequest request)

通知主机应用程序Web内容请求访问指定资源的权限,并且当前未授予或拒绝权限。宿主应用程序必须调用PermissionRequest#grant(String[])或PermissionRequest#deny()。如果此方法未被重写,则拒绝该权限。

  • onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback)

通知主机应用程序,来自指定来源的Web内容试图使用地理定位API,但目前没有为该源设置许可状态。宿主应用程序应该调用具有所需权限状态的指定回调。有关详细信息,请参阅GeolocationPermissions。

  • onGeolocationPermissionsHidePrompt()

如果上面那个权限取消会调用这个,因为没有权限,所以相关ui应该被隐藏。

  • onPermissionRequestCanceled(PermissionRequest request)

通知主程序权限请求被取消。相关ui应该被隐藏。

  • onReceivedTitle(WebView view, String title)

通知主程序document title变化。

  • onReceivedIcon(WebView view, Bitmap icon)

通知主程序当前页面有新的favicon。

  • onReceivedTouchIconUrl(WebView view, String url, boolean precomposed)

通知主程序的apple-touch-icon的url。apple-touch-icon用于给苹果设备生成桌面快捷方式.

  • onShowCustomView(View view, CustomViewCallback callback)

通知主机应用程序当前页面已进入全屏模式。主应用程序必须在全屏幕模式下显示包含Web内容(视频或其他HTML内容)的自定义视图。也请参阅WebView里的“全屏支持”文档。

  • onHideCustomView()

通知主程序当前页面已经退出全屏模式。主程序需要隐藏自定义view。

  • onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)

请求主机应用程序创建一个新窗口。如果宿主应用程序选择尊重这个请求,它应该从这个方法返回true,创建一个新的WebView来托管窗口,将它插入到视图系统中,并以新的WebView作为参数将提供的resultMsg消息发送到它的目标。如果宿主应用程序选择不履行请求,则应该从该方法返回false。此方法的默认实现不执行任何操作,因此返回false。

  • onRequestFocus(WebView view)

此WebVIEW请求显示和焦点。这可能是由于另一WebVIEW在这个WebVIEW中打开一个链接并请求显示这个WebView。

  • onCloseWindow(WebView window)

通知主机应用程序关闭给定的WebVIEW,并在必要时从视图系统中删除它。在这一点上,WebCore已经停止了这个窗口中的任何加载,并删除了JavaScript中的任何互相访问能力。

  • onJsAlert(),onJsConfirm(),onJsPrompt()

接收js三种对话框事件的,返回true则app处理,否则网页webview自己处理.

  • onJsBeforeUnload(WebView view, String url, String message, JsResult result)

告诉客户端显示一个对话框以确认导航离开当前页面。这是预先卸载JavaScript事件的结果。如果客户端返回true,WebVIEW将假定客户端将处理确认对话框并调用适当的JSREST方法。如果客户端返回false,则true值将返回到JavaScript以接受当前页面的导航。默认行为是返回false。将JSRESULT设置为true将导航离开当前页面,false将取消导航。

  • onConsoleMessage(ConsoleMessage consoleMessage)

向主机应用程序报告一个JavaScript控制台消息。ChromeClient 应该重写这个过程来处理日志消息,因为它们看起来合适。

  • Bitmap getDefaultVideoPoster()

当不播放时,视频元素由'poster' 图像表示。可以使用HTML中的视频标签的poster 属性来指定要使用的图像。如果属性不存在,则将使用默认poster 。此方法允许ChromeClient 提供默认图像 

  • View getVideoLoadingProgressView()

获取在全屏视频正在缓冲的同时显示的视图。宿主应用程序可以重写此方法,以提供包含旋转器或类似物的视图。

  • getVisitedHistory(ValueCallback callback)

获取历史访问记录

  • onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams)

告诉客户端显示一个文件选择器。这被调用来处理带有“文件”输入类型的HTML表单,以响应用户按下“选择文件”按钮。要取消请求,请调用filePathCallback.onReceiveValue(null)并返回true。

  • setupAutoFill(Message msg)

告诉客户端正在查看的页面有一个可自动填充的表单,用户希望设置一个配置文件。

5. pauseTimers(),pause(), resume()

当webview所在的activty退入后台或者呈现前台的时候,为了节省电源,在activity的onResume()和onPause()方法里会调用这三个方法。

  • pause(), 是让javascript不再运行,整个webview都不再解析。这样就节省了电源和内存。在activity 的onPause()方法里会调用。
  • resume(),和pause()正好相反。 在activity 的onResume()方法里会调用。
  • pauseTimers(),暂停所有的布局layout, 解析parsing, 和 JavaScript的计时器 timers。注意这里有坑!pauseTimers()这个方法是对所有webview对象有效果的。我遇到的一个case是: WebViewActivity中跳出广告AdvActivity。这时WebViewActivity被广告AdvActivity挡住了,所以WebViewActivity调用了onPause()并且调用了pauseTimer(). 结果导致广告倒计时无效!因为广告AdvActivity也是靠WebView呈现内容的。pauseTimers()这个方法不要随便调用,更不要在onDestory()里调用。

6. 销毁WebView对象

这个没什么好说的,总之就是唯恐销毁不掉的感觉。可能怕延迟销毁。

    @Override
    protected void onDestroy() {

        if (mWebView != null) {
            mWebView.clearHistory();
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.loadUrl("about:blank");
            mWebView.stopLoading();
            mWebView.setWebChromeClient(null);
            mWebView.setWebViewClient(null);
            mWebView.destroy();
            mWebView = null;
        }

        super.onDestroy();
    }

7. 白屏与错误页面处理

  1. 当网络不好或者页面比较丰富时会显示白屏。这个时候我们可以先加载自己的等待html。等正式页面加载完后会自动替换等待页面。等待页面html可以先缓存在assert文件夹下面,同样图片资源文件也要放在assert文件夹。html页面中用"file:///xxxxx"做为image的src。
  2. 同样当网络异常的时候,也可以用异常html替换,道理是一样的。在onReceivedError()方法中接到网络异常的时候就加载异常页面html.
  3. html内容可以作为html文件放在assert文件夹,也可以在java里定义成string。当页面需要做国际化多语言的时候,定义成String相对简单一些。也可以根据local环境加载不同的html文件。
  4. 在页面中一定要加入这句。可以适配手机屏幕大小。不然可能出现滑动条。
String WEB_VIEW_LOAD_ERROR_PAGE = "" +
            "" +
            "" +
            "    " +
            "    " +
            "    " +
            "" +
            "" +
            "
" + " " + "

[title]

" + "

[body]

" + "
" + "" + ""; if (TextUtils.isEmpty(mHtml)) { mHtml = Constants.WEB_VIEW_LOAD_ERROR_PAGE.replace("[title]", getString(R.string.Network_Problem)).replace("[body]", getString(R.string.check_network_problem)); } mWebView.loadDataWithBaseURL(null, mHtml, "text/html", "UTF-8", null);

8. 上/下一个页面

private void goBack(){
        if (mWebView.canGoBack()){
            mWebView.goBack();
        }
    }

private void goForward() {
        if (mWebView.canGoForward()) {
            mWebView.goForward();
        }
    }

9. 下载

通过DownloadListener可以拿到下载相关的信息。

/×
Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
格式说明: content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm )  
字段说明:Content-Disposition为属性名disposition-type是以什么方式下载,如attachment为以附件方式下载disposition-parm为默认保存时的文件名服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment 
×/

mWebView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
                                        long contentLength) {

            }
        });

10. 缓存策略

    //优先使用缓存: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
        //缓存模式如下:
        //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
        //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
        //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
        //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

    //不使用缓存: 
    WebView.getSettings().setCacheMode(WebSettings.LOAD_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 缓存目录

 

11. JS的交互

对于Android调用JS代码的方法有2种: 
1. 通过WebViewloadUrl().
2. 通过WebViewevaluateJavascript(). 要求android4.4以上

对于JS调用Android代码的方法有3种: 
1. 通过WebViewaddJavascriptInterface()进行对象映射 
2. 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url 
3. 通过 WebChromeClient 的onJsAlert()onJsConfirm()onJsPrompt()方法回调拦截JS对话框alert()confirm()prompt() 消息

4. 到了2020年了,市场上还有多少android 4.2,4.4的手机呢?! 所以JS--->JAVA就用addJavascriptInterface()这种方式吧, JAVA--->JS就用evaluateJavascript()吧。

 

另外,注意事项:

  • webview.loadUrl("javascript:show()"); 要在UI线程。以及JS回调过来的方法也必须在UI线程执行。
  • 有一个交互框架JSBridge。Android WebView 全面干货指南
  • JS交互网上比较好的文章是:Android:你要的WebView与 JS 交互方式 都在这里了,这篇漏洞的也看看,主要是针对addJavascriptInterface这种方式,但是第4条已经说了现在的情况。你不知道的 Android WebView 使用漏洞

下面是对loadUrl方式的简单使用:

index.html 放在assets目录下面:




    
    
    webview study






 

public class MainActivity extends AppCompatActivity {
    private WebView mWebView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWebView = (WebView) findViewById(R.id.webView);

        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setDomStorageEnabled(true);

        mWebView.addJavascriptInterface(new JsOperations(this), "client");

        mWebView.loadUrl("file:///android_asset/index.html");
    }

    public void onClick(View view) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mWebView.loadUrl("javascript:click()");
            }
        });
    }
}

 

11. WebView的简单实用的完整代码如下:

public class WebViewActivity extends AppCompatActivity {

    private WebView mWebView;   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
      
        mWebView = (WebView) findViewById(R.id.webView);

        //Webview的设置接口都在WebSettings类里面。
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);//支持javascript
        webSettings.setUseWideViewPort(true); //设置使web页自适应屏幕
        webSettings.setLoadWithOverviewMode(true);////缩放至屏幕的大小
        webSettings.setSupportZoom(false); //设置支持缩放
        webSettings.setBuiltInZoomControls(false); //在网页上添加放大缩小的控件
        webSettings.setDisplayZoomControls(false); //在网页上显示放大缩小的控件
        webSettings.setLoadsImagesAutomatically(true); //设置自动加载图片

        webSettings.setBlockNetworkImage(true);    //设置网页在加载的时候暂时不加载网络图片
        webSettings.setAppCachePath("");   //设置缓存路径
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);   //设置缓存模式

  
        webSettings.setAllowFileAccess(true); //设置可以访问file:///文件.有安全问题需要注意。


        mWebView.loadUrl("https://www.csdn.net/");
       

        showProgress(true);
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                String url = request.getUrl().toString();

                try {
                    if (url.startsWith("http:") || url.startsWith("https:")) {
                        view.loadUrl(url);
                    } else {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                    }
                } catch (Exception e) {
                    return false;
                }
                return true;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                showProgress(false);
            }

            @Override
            public void onPageFinished(WebView view, String url) {

            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                //also will be schema error, not network error.
                if (errorCode == WebViewClient.ERROR_TIMEOUT
                        || errorCode == WebViewClient.ERROR_HOST_LOOKUP
                        || errorCode == WebViewClient.ERROR_CONNECT
                        || errorCode == WebViewClient.ERROR_PROXY_AUTHENTICATION) {
                    if (TextUtils.isEmpty(mHtml)) {
                        mHtml = Constants.WEB_VIEW_LOAD_ERROR_PAGE.replace("[title]", getString(R.string.Network_Problem)).replace("[body]", getString(R.string.check_network_problem));
                    }

                    mWebView.loadDataWithBaseURL(null, mHtml, "text/html", "UTF-8", null);
                }
            }
        });

    @Override
    protected void onResume() {
        super.onResume();
        mIsResumed = true;
        mWebView.onResume();
        mWebView.resumeTimers();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mIsResumed = false;
        mWebView.onPause();
        mWebView.pauseTimers();//这方法慎重使用
    }

    @Override
    protected void onDestroy() {

        if (mWebView != null) {
            mWebView.clearHistory();
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.loadUrl("about:blank");
            mWebView.stopLoading();
            mWebView.setWebChromeClient(null);
            mWebView.setWebViewClient(null);
            mWebView.destroy();
            mWebView = null;
        }

        super.onDestroy();
    }

    @Override
    public void onBackPressed() {

        if (mWebView.canGoBack()) {
            mWebView.goBack();
            return;
        }

        super.onBackPressed();
    }
}


public class Constants {

    public static String WEB_VIEW_LOAD_ERROR_PAGE = "" +
            "" +
            "" +
            "    " +
            "    " +
            "    " +
            "" +
            "" +
            "
" + " " + "

[title]

" + "

[body]

" + "
" + "" + ""; }

WebView的简单介绍就到这里,倘若以后还有使用经历会继续补充。

 

 

你可能感兴趣的:(Android WebView的简单使用和注意事项。)