WebView详解

来源:互联网 发布:linux dd命令 制作iso 编辑:程序博客网 时间:2024/04/29 05:57

WebView详解

1. 应用场景

2. 相关概念

问题: Android应用中显示文字用TextView控件、显示图片使用ImageView控件,那么如果想在app中显示一个网页内容,该使用什么控件呢?

可以有两种方式:

1.调用系统内置的浏览器应用
2.WebView

  • 概念:webView 是一个可以显示网页的控件,他的网页渲染引擎和Safari、Chrome一样都是Webkit(一个开源的浏览器引擎)。
  • 功能:在Activity中你想调用自己的web浏览器显示网页上的内容时就要使用WebView组件,它使用WebKit引擎显示网页并且提供方法对

    • 历史浏览的网页前进,
    • 后退,
    • 放大和缩小,
    • 搜索等等
  • 优势: 使用webView来开发应用,有几个很明显的优势:

    • 1.搭建Java和Javascript之间交互的桥梁
    • 2.跨平台,网页代码编写一次,即可以在任何支持web的平台上运行,如adnroid iphone win节省开发成本,提高开发效率。
    • 3.资源利用最大化,web开发人员只用很少的学习成本即可以使用webView开发。
    • 4.应用程序维护成本大大降低,只用维护服务器端代码即可。

    即有本地应用的功能,又有B/S应用(Browser/Server浏览器/服务器)模式的优势,可以说是二者的结合体

3.注意事项

  • 3.1 webView ?必须添加Internet权限,否则报Web page not available错误

4.常用方法

4.1 加载页面的方式

  • webView.loadUrl(String url) 直接加载网页、图片并显示

    • 本地资源:
      • 加载项目assets下的文件 webView.loadUrl(“file:///android_asset/x.html”);
      • 加载sdcard下的index.html文件 webView.loadUrl(“file:///sdcard/index.html”);
    • 远程资源: webView.loadUrl(“http://www.baidu.com“);
  • loadData (data, mimeType, encoding)

    • data:要加载的网页内容。不能是网址。
    • mimetype:加载的网页内容的类型(text/html,image/jpeg)
    • encoding:指定编码utf-8或者gbk
      事实证明这个经常会出现中文乱码
    • API提供的标准用法,无法解决乱码问题 webView.loadData(data, “text/html”, “UTF -8”); 修改为  webView.loadData(data, “text/html; charset=UTF-8”, null); 可以正确解码

    注解:loadData不支持#、%、\、? 四种字符。但也不是完全不支持,表现很怪异。

  • loadDataWithBaseURL(baseUrl, data, mimeType, encoding, failUrl)

    参数说明: 此方法可以解决loadData的中文乱码问题。提倡使用这个。

    • baseUrl:是图片的目录,在html代码中就写关于此目录的相对路径。
    • failUrl:从baseUrl中加载失败后,从这个目录中加载。
    • 其它三个参数同loadData方法一样。
  • WebView 三大辅助类

    4.2 WebView的常用设置属性WebSetting

    • 获取方式: WebSetting ws=webView.getSettings()

    常用方法

    • 支持通过js打开新的窗口 settings.setJavaScriptCanOpenWindowsAutomatically(true)
    • 支持加载javaScript,默认是false settings.setJavaScriptEnabled(true)
    • 支持放大缩小 settings.setSupportZoom(true)
    • 设置webView的默认缩放 settings.setDefaultZoom(ZoomDensity.FAR)
    • 设置为支持插件,如flashPlayer插件 settings.setPluginsEnabled(true)
    • 打开自带的缩放按钮(支持出现放大缩小工具) settings.setBuiltInZoomControls(true)

    4.3 WebChromeClient 主要处理控件,eg. progressbar

    • webView辅助chrome处理Javascript的对话框,网站图标,网站title;
    • 处理弹出框、确认框、输入框

      • 弹出框
        WebView.setWebChromeClient(new WebChromeClient() {
        public boolean onJsAlert(WebView view, String url, String message,JsResult result) {
        return super.onJsAlert(view, url, message, result);}
      • 确认框
        public boolean onJsConfirm(WebView view, String url,String message, JsResult result) {
        return super.onJsConfirm(view, url, message, result);}
      • 输入框
        public boolean onJsPrompt(WebView view, String url, String message,String defaultValue, JsPromptResult result) {
        return super.onJsPrompt(view, url, message, defaultValue, result);}
        })

      应用情形:当遇到影响浏览网页的一些事情。比如显示进度条或弹出js对象框,就需要设置

    • onProgressChanged 改变进度条

      `onProgressChanged(WebView view, int newProgress)`

    4.4 WebViewClient 主要处理事件,eg 监听事件

    • 设置WebView连接时状态的设置,负责处理解析,渲染网页等浏览器做的事。
    • webView.setWebViewClient(new WebViewClient() { });
      • shouldOverrideUrlLoading  如何加载,当前web重新加载一个url
      • onPageStarted 开始加载
      • onPageFinished 加载完成
      • onReceivedError 接受到错误时执行
        应用情形:当影响网页渲染内容的事情发生时,比如,加载出现错误,我们就可以它拦截错误。

    5. 基本功能实现 主要代码

    需求:主要功能

    1. 点击,在 edit 里面查询数据,如果以com 结尾就查询
    2. 在 edit 下面有progerss ,当加载的时候显示进度
    3. 设置 javas
    4. 设置回滚

    5.1 设置支持JavaScript

    `   private void initWebView() {    //得到webSetting    WebSettings setting=manger_wv.getSettings();    setting.setJavaScriptCanOpenWindowsAutomatically(true);    setting.setJavaScriptEnabled(true);    }`

    5.2 设置滚动条

    `manger_wv.setWebChromeClient(new WebChromeClient(){        @Override        public void onProgressChanged(WebView view, int newProgress) {            manger_pb.setVisibility(View.VISIBLE);            //将网页加载的进度值传递给控件 manger_pb            manger_pb.setProgress(newProgress);            //当网页加载完成时,隐藏进度条            if(newProgress==100){                manger_pb.setVisibility(View.GONE);            }        }`

    5.3 设置 设置在当前页面进行加载

    `wv.setWebViewClient(new WebViewClient(){        //捕捉网页中的超连接        @Override        public boolean shouldOverrideUrlLoading(WebView view, String url) {            //在输入框中显示超连接的url            etPath.setText(url);            //TODO:打开系统的浏览器显示url指示的网页            return super.shouldOverrideUrlLoading(view, url);        }        //在网页加载完成时被回调        @Override        public void onPageFinished(WebView view, String url) {            Toast.makeText(Main2Activity.this, "加载完成!", 0).show();        }        //当加载出现错误时被回调        @Override        public void onReceivedError(WebView view, int errorCode,                String description, String failingUrl) {            Toast.makeText(Main2Activity.this, description, 0).show();        }    });`

    5.4 添加文字改变的监听事件

    `manger_et.addTextChangedListener(new TextWatcher() {        //重写相关的三个方法        @Override        public void onTextChanged(CharSequence s, int start, int before, int count) {            //当文字改变的时候            String path=s.toString().trim();            if(path.endsWith("com")){                //加载网页                manger_wv.loadUrl(path);            }        }        @Override        public void beforeTextChanged(CharSequence s, int start, int count,                int after) {        }        @Override        public void afterTextChanged(Editable s) {        }    });`

    5.5 设置 返回键

    `   public boolean onKeyDown(int keyCode, KeyEvent event) {    //判断  代表返回按钮    if(keyCode==KeyEvent.KEYCODE_BACK){        if(manger_wv.canGoBack()){            manger_wv.goBack();//返回上一级页面        }else{            finish();        }    }    return true;}`

    完整代码

    布局文件

        `<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <EditText        android:id="@+id/manger_et"        android:layout_width="match_parent"        android:layout_height="wrap_content" />    <ProgressBar        android:id="@+id/manger_pb"        android:layout_below="@id/manger_et"        style="?android:attr/progressBarStyleHorizontal"        android:layout_width="match_parent"        android:layout_height="wrap_content" />    <WebView        android:id="@+id/manger_wv"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_below="@+id/manger_pb" />    </RelativeLayout>`

    代码块

        `public class MangerActivity extends Activity {    private EditText manger_et;    private ProgressBar manger_pb;    private WebView manger_wv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_manger);        //初始化控件        initView();        //设置支持Js        initWebView();        //初始化事件        initEvent();    }    private void initWebView() {        //得到webSetting        WebSettings setting=manger_wv.getSettings();        setting.setJavaScriptCanOpenWindowsAutomatically(true);        setting.setJavaScriptEnabled(true);    }    private void initEvent() {        //设置滚动条        manger_wv.setWebChromeClient(new WebChromeClient(){            @Override            public void onProgressChanged(WebView view, int newProgress) {                manger_pb.setVisibility(View.VISIBLE);                //将网页加载的进度值传递给控件 manger_pb                manger_pb.setProgress(newProgress);                //判断 当进度慢了,进度条消失                if(newProgress==100){                    manger_pb.setVisibility(View.GONE);                }            }        });        //edit 设置监听事件        manger_et.addTextChangedListener(new TextWatcher() {            //重写相关的三个方法            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                //当文字改变的时候                String path=s.toString().trim();                if(path.endsWith("com")){                    //加载网页                    manger_wv.loadUrl(path);                }            }            @Override            public void beforeTextChanged(CharSequence s, int start, int count,                    int after) {                // TODO Auto-generated method stub                }            @Override            public void afterTextChanged(Editable s) {            }        });    }    private void initView() {        manger_et = (EditText) findViewById(R.id.manger_et);        manger_pb = (ProgressBar) findViewById(R.id.manger_pb);        manger_wv = (WebView) findViewById(R.id.manger_wv);        //开始设置 进度条 不可见        manger_pb.setVisibility(View.GONE);        //设置 wv 在本地显示  Client 为客户端         manger_wv.setWebViewClient(new WebViewClient(){            //展示 uti 地址            @Override            public boolean shouldOverrideUrlLoading(WebView view, String url) {                manger_et.setText(url);                //设置隐式跳转                Intent intent=new Intent();                intent.setAction("android.intent.action.VIEW");                Uri content_utl=Uri.parse(url);                intent.setData(content_utl);                startActivity(intent);                return super.shouldOverrideUrlLoading(view, url);            }            @Override            public void onPageFinished(WebView view, String url) {                Toast.makeText(MangerActivity.this, "加载完成..", 0).show();                manger_et.setText(url);            }            @Override            public void onReceivedError(WebView view, int errorCode,                    String description, String failingUrl) {                Toast.makeText(MangerActivity.this, description, 0).show();            }        });//设置wv 的客户端    }//设置 返回键     @Override    public boolean onKeyDown(int keyCode, KeyEvent event) {        //判断        if(keyCode==KeyEvent.KEYCODE_BACK){            if(manger_wv.canGoBack()){                manger_wv.goBack();            }else{                finish();            }        }        return true;    }    }`

    6. Java 与 JS 互调

    6.1 WebView里,JS调用Java

    Js调用Java:

    • webView.addJavascriptInterface(Object obj, String interfaceName)//
      • 把java类注册成javacript对象,以便调用;参数一:要调用的对象,参数二:x需要被js调用的对外接口名
    • 在Android4.2极其以上系统需要给提供js调用的方法前加入一个注解:@JavaScriptInterface; 如:
    • Html页面中调用写法:
      window.interfaceName.方法名()或者是javascript: interfaceName.方法名() ;

    6.2 WebView里,Java调用JS

    • webView.loadUrl(“javascript:js函数名 “)

      确保当前已经加载html页面,然后用该方法

    0 0