webview详解和常见的问题

1.如果访问的界面中有JavaScript,则webview必须支持javascript。

WebSettings webSetting = webview.getSetting();
 webSetting.setJavaScriptEnabled(true);

2.如果页面中链接,如果希望点击链接继续在当前browser中响应,而不是新开Android的系统browser中响应该链接,必须覆盖webview的WebViewClient对象。

mWebView.setWebViewClient(new WebViewClient(){
    public boolean shouldOverrideUrlLoading(WebView view, String url) {      
        view.loadUrl(url);      
        return true;      
    }      
}

3.如果不做任何处理,浏览网页,点击系统“Back”键,整个Browser会调用finish()而结束自身,如果希望浏览的网页回退而不是推出浏览器,需要在当前Activity中处理并消费掉该Back事件。

 public boolean onKeyDown(int keyCode, KeyEventevent) {      
            if((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {      
                mWebView.goBack();      
                return true;      
            }      
         return super.onKeyDown(keyCode, event);      
     }

4.如果webView中需要用户手动输入用户名、密码或其他,则webview必须设置支持获取手势焦点。

webview.requestFocusFromTouch();

5.原来是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下载。具体操作如下:

1、设置WebView的DownloadListener:
    webView.setDownloadListener(new MyWebViewDownLoadListener());
2、实现MyWebViewDownLoadListener这个类,具体可以如下这样:    
    private class MyWebViewDownLoadListener implements DownloadListener {  
        @Override  
        public void onDownloadStart(String url, String userAgent, String 
        contentDisposition, String mimeType, long contentLength) {  
        Uri uri = Uri.parse(url);  
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);  
        startActivity(intent);  
    }  

}  
这只是调用系统中已经内置的浏览器进行下载,还没有WebView本身进行的文件下载,
不过,这也基本上满足我们的应用场景了。

WebSettings的常用方法介绍

1.setJavaScriptEnabled(true);
//支持js脚步

2.setPluginsEnabled(true);
//支持插件

3.setUseWideViewPort(false);
//将图片调整到适合webview的大小

4.setSupportZoom(true);
//支持变焦控制和手势缩放

5.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
//支持内容从新布局

6.supportMultipleWindows();
//多窗口

7.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//关闭webview中缓存

8.setAllowFileAccess(true);
//设置可以访问文件

9.setNeedInitialFocus(true);
//当webview调用requestFocus时为webview设置节点

10.setBuiltInZoomControls(true);
//Sets whether the WebView should use its built-in zoom mechanisms.设置其webview内置的缩放机制

11.setJavaScriptCanOpenWindowsAutomatically(true);
//支持通过JS打开新窗口

12.setLoadsImagesAutomatically(true);
//支持自动加载图片

WebViewClient的方法全解

1.doUpdateVisitedHistory(WebViewview,Stringurl, boolean isReload)
(更新历史记录)
2.onFormResubmission(WebViewview,MessagedontResend,Messageresend)
(应用程序重新请求网页数据)
3.onLoadResource(WebViewview,Stringurl)
在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。
4.onPageStarted(WebViewview,Stringurl,Bitmapfavicon)
这个事件就是开始载入页面调用的,通常我们可以在这设定一个loading的页面,告诉用户程序在等待网络响应。
5.onPageFinished(WebViewview,Stringurl)
在页面加载结束时调用。同样道理,我们知道一个页面载入完成,于是我们可以关闭loading 条,切换程序动作。
6.onReceivedError(WebViewview, int errorCode, Stringdescription,StringfailingUrl)
(报告错误信息)
7.onReceivedHttpAuthRequest(WebViewview,HttpAuthHandlerhandler,Stringhost,Stringrealm)
(获取返回信息授权请求)
8.onReceivedSslError(WebViewview,SslErrorHandlerhandler,SslErrorerror)
重写此方法可以让webview处理https请求。
9.onScaleChanged(WebViewview, float oldScale, float newScale)
(WebView发生改变时调用)
10.onUnhandledKeyEvent(WebViewview,KeyEventevent)
(Key事件未被加载时调用)
11.shouldOverrideKeyEvent(WebViewview,KeyEventevent)
重写此方法才能够处理在浏览器中的按键事件。
12.shouldOverrideUrlLoading(WebViewview,Stringurl)
在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。这个函数
我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作。

常用步骤

1、添加上网权限:

2、设置webview

WebView webView = new WebView(this);
WebSettings ws = webView.getSettings();
ws.setAppCacheEnabled(true);// 设置启动缓存
ws.setAppCacheMaxSize(1024 * 10);// 设置最大缓存
ws.setSupportZoom(true);// 设置支持缩放
ws.setBuiltInZoomControls(true);
ws.setCacheMode(WebSettings.LOAD_NO_CACHE);// 设置缓存模式
// 设置支持Javascript
ws.setJavaScriptEnabled(true);
ws.setJavaScriptCanOpenWindowsAutomatically(true);
// 缓存,离线应用
ws.setAppCacheEnabled(true);
ws.setCacheMode(WebSettings.LOAD_DEFAULT);
ws.setAppCacheMaxSize(1024 * 1024 * 8);

3、获取网页对话框

webView.setWebChromeClient(new WebChromeClient() {
    @Overridepublic boolean onJsAlert(WebView view, String url, String message,final JsResult result) {
    //构建一个Builder来显示网页中的对话框Builder builder = new Builder(context);
        builder.setTitle("警告");
        builder.setMessage(message);
        builder.setPositiveButton(android.R.string.ok,new AlertDialog.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {// 点击确定按钮之后,继续执行网页中的操作
            result.confirm();
            }
        });
        builder.setCancelable(false);
        builder.create();
        builder.show();return true;
    }

    @Overridepublic boolean onJsConfirm(WebView view, String url,
    String message, final JsResult result) {// TODO Auto-generated method stub
        Builder builder = new Builder(context);
        builder.setTitle("confirm");
        builder.setMessage(message);
        builder.setPositiveButton(android.R.string.ok,new AlertDialog.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                result.confirm();
            }
        });
        builder.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                result.cancel();
            }
        });
        builder.setCancelable(false);
        builder.create();
        builder.show();
        return true;
    }
    @Overridepublic void onProgressChanged(WebView view, int newProgress) {// 加载进度//
        super.onProgressChanged(view, newProgress);
    }
});

4、如果希望点击链接由自己处理,而不是新开Android的系统browser中响应该链接。
给WebView添加一个事件监听对象(WebViewClient)

5、webview取得焦点

6、提示加载对话框

pd=ProgressDialog.show(context, "请稍后", "正在加载中...");
当网页加载完成后,调用pd.dismiss();

webview和js之间数据的传送操作

Webview与js交互

Webview与js的双向交互才是android的webview强大所在,也是马甲精神能够彻底执行的基础保障。
将WebView接受到的数据传递给js
首先,webview可以定义一个在其内嵌页面中可以触发的事件

wv.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
private final class DemoJavaScriptInterface {  
    public void clickonAndroid( final String order){  
        mHandler.post(new Runnable(){  
            @Override  
             public void run(){  
                 sonText="{"name":""+order+""}";  
                 wv.loadUrl("javascript:wave("+jsonText+")");  
             }  
        });  
}  

将js接受到的数据传递给webview
如果你想获取页面的一些处理数据并交给webview客户端处理,可在wave函数里将数据alert,然后webview中重写WebChromeClient的onJsAlert函数,具体代码如下:

wv.setWebChromeClient(new MyWebChromeClient());  
final  class MyWebChromeClient extends WebChromeClient{  
//message就是wave函数里alert的字符串,这样你就可以在android客户端里对这个数据进行处理  
    @Override 
    public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
        result.confirm(); 
        return true;    
    } 
}

loadData和loadDataWithBaseURL区别

loadData (String data, String mimeType, String encoding)

加载一段HTML代码时,如果出现中文乱码问题,
就写成loadData(String data, "text/html;charset=UTF-8",null)

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

loadDataWithBaseURL()比loadData()多两个参数,可以指定HTML代码片段中相关资源的相对根路径,也可以指定历史Url。
两个方法的其余三个参数相同。
其次,两个方法加载的HTML代码片段有些不同,loadData()中的html data中不能包含'#', '%', '\', '?'四中特殊字符,这

WebView加载本地的css文件,js文件和图片,主要是覆盖WebViewClient中的shouldInterceptRequest(View view, String url)方法:

cacheWebview.setWebViewClient(new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

            WebResourceResponse response = super.shouldInterceptRequest(view, url);

            if (url.contains("weixin_qrcode_258.jpg")){
                InputStream inputStream = null;
                try {
                    inputStream = getResources().getAssets().open("weixin_qrcode_258.jpg");
                    response = new WebResourceResponse("image/png",
                            "utf-8", inputStream);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }else if(url.contains(jsName)){
               InputStream is = appRm.getInputStream(R.raw.jquery_min_js);
               WebResourceResponse response = new WebResourceResponse("text/javascript","utf-8", is);
            }else if(url.contains(cssName)){
               InputStream is = appRm.getInputStream(R.raw.css;
               WebResourceResponse response = new WebResourceResponse("text/css","utf-8", is);
            }
            return response;

        }
    });

加载assets文件夹下面的html资源

webView.loadUrl("file:///android_asset/1.html");

调用js可能出现的错误

Alert无法弹出
你应该是没有设置WebChromeClient,按照以下代码设置
myWebView.setWebChromeClient(new WebChromeClient() {});

Uncaught ReferenceError: functionName is not defined
问题出现原因,网页的js代码没有加载完成,就调用了js方法。解决方法是在网页加载完成之后调用js方法
myWebView.setWebViewClient(new WebViewClient() {
    @Override
    public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);
      //在这里执行你想调用的js函数
    }
});

原文: webview详解和常见的问题
作者: appzy

你可能感兴趣的:(webview详解和常见的问题)