android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)

1.前言

最近几年混合应用越来越流行,及一部分功能用原生代码开发,一部分功能用html5实现。那什么时候用原生什么时候用网页呢?很多人第一反应就是经常变化的页面用网页开发,避免经常发包,不全对。其实因为网页使用体验远远不及原生开发,所以一般有以下两种情况建议使用网页代替原生:
1.试水功能
2.类似双11主会场,这类只在固定时间内使用的功能。

2.基本使用方法

1)xml布局:




    

    

    


2)利用WebSettings设置一些页面属性,比如,页面字体的大小,是否支持js,支持缩小放大,支持本地存储,支持缓存等。

public static void initWebSettings( WebView webView) {
        WebSettings webSettings = webView.getSettings();
        webSettings.setDefaultTextEncodingName("UTF-8");//设置默认为utf-8
        webSettings.setTextZoom(100);//设置WebView中加载页面字体变焦百分比,默认100
        //属性可以让webview只显示一列,也就是自适应页面大小,不能左右滑动
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING);
        } else {
            webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NORMAL);
        }

        //设置此属性,可任意比例缩放
        webSettings.setUseWideViewPort(false);
        webSettings.setLoadWithOverviewMode(true);

        //页面支持缩放
        webSettings.setBuiltInZoomControls(false);
        webSettings.setSupportZoom(false);
        webSettings.setDisplayZoomControls(false);
        //设置支持js
        webSettings.setJavaScriptEnabled(true);
        webSettings.setSavePassword(false);
        //设置 缓存模式
        webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
        // 开启 DOM storage API 功能
        webSettings.setDomStorageEnabled(true);

        webView.setVerticalScrollBarEnabled(false);
        webView.setVerticalScrollbarOverlay(false);
        webView.setHorizontalScrollBarEnabled(false);
        webView.setHorizontalScrollbarOverlay(false);

    }

3)加载内容
(1)加载assets目录下的本地网页
一般我们都是把html文件放在assets目录下, WebView调用assets目录下的本地网页和图片等资源非常方便,如下代码所示:

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

(2)加载远程网页

webView.loadUrl("http://www.baidu.com/");

(3)使用 LoadData 或者 loadDataWithBaseURL方法加载内容
有时候我们的webview可能只是html片段,而不是一个完整的网页,事实上绝大多数时候都是如此,完整的网页无需做成应用,而直接在浏览器访问。这种情况我们使用 LoadData 或者 loadDataWithBaseURL方法,后者用的最多:

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

loadDataWithBaseURL()比loadData()多两个参数,可以指定HTML代码片段中相关资源的相对根路径,也可以指定历史Url,其余三个参数相同。

这里主要注意参数baseUrl,baseUrl指定了你的data参数中数据是以什么地址为基准的,因为data中的数据可能会有超链接或者是image元素,而很多网站的地址都是用的相对路径,如果没有baseUrl,webview将访问不到这些资源。如下所示:

String body ="示例:这里有个img标签,地址是相对路径";
mWebView.loadDataWithBaseURL("http://baidu.com", body, "text/html", "utf-8",null);

如果baseUrl没有指定为http://baidu.com,那么这张图片将显示不出来。


到这里,基本的webview功能已经可以使用了。

3.android应用中拦截js点击跳转,替换成跳转到原生界面。

实际项目中,可能会显示网页标题,需要展示加载进度,或者当点击网页中一个按钮或者一个商品,需要跳转到原生界面,这个时候就需要用到两个方法:
WebViewClient主要用来拦截网页中的请求,开始,结束请求等操作。

webView.setWebViewClient(new WebViewClient() {

            //返回值:true 不会显示网页资源,需要等待你的处理,false 就认为系统没有做处理,会显示网页资源
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //当url里面包含webview字段的时候,则跳转到ShowActivity原生页面,否则还是继续显示网页
                //比如:在百度输入框里面输入webview在点击搜索,再点击任何有webview字段的链接,
                //则不继续显示网页,而是跳转到自己定义的原生页面
                if (!TextUtils.isEmpty(url)
                        && url.contains("webview")) {
                    Intent intent = new Intent(ClickInterceptionActivity.this, ShowActivity.class);
                    intent.putExtra("url", url);
                    startActivity(intent);
                    return true;
                }
                return false;
            }

            //在页面开始加载时候做一些操作,比如展示进度条
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                webview_progressbar.setVisibility(View.VISIBLE);
                super.onPageStarted(view, url, favicon);
            }
            //在页面加载完成的时候做一些操作,比如隐藏进度条
            @Override
            public void onPageFinished(WebView view, String url) {
                webview_progressbar.setVisibility(View.GONE);
                super.onPageFinished(view, url);
            }
        });

WebChromeClient主要辅助WebView处理JavaScript的对话框、网站图标、网站title、加载进度等。

 webView.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                webview_progressbar.setProgress(newProgress);
                super.onProgressChanged(view, newProgress);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                title_name.setText(title);
                super.onReceivedTitle(view, title);
            }

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
            }

        });

效果如下所示:带有加载进度和标题
android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)_第1张图片
当在输入框中webview,并点击【百度一下】,正常情况会进入搜索结果网页,由于我们重写了shouldOverrideUrlLoading方法,对url实现了拦截,则跳转到原生页面。
android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)_第2张图片
android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)_第3张图片

4.js和Java的交互

除了上面的简单展示,很多项目中还会有js跟java的双向交互。

1)js调用android原生方法

1.addJavascriptInterface

webView.addJavascriptInterface(new clickOnJS(), "click");

2.在android中定义待调用方法:

 class clickOnJS {
        @JavascriptInterface
        public void OnClick() {
            Toast.makeText(IntermodulationActivity.this, "调用java成功", Toast.LENGTH_SHORT).show();
        }

    }

3.js定义方法去调用java方法。

$(function(){
      $('.payment').click(function(){
            window.click.OnClick();
        });

    });

效果如下图所示:点击【js调用java】按钮,则弹出toast,证明成功调用java原生方法。
android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)_第4张图片

2)android调用js方法
当点击android页面上某个按钮的时候,改变js页面的内容,其实就是android原生给js传值。
1.点击标题,则调用js方法

title_name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //调用js方法
                webView.loadUrl("javascript:setcontent(2)");
            }
        });

2.js代码实现,修改cr的值

function setcontent(content){
          $('.num ,.cr').text(content);
        }

效果如下图所示:点击标题,则调用js的setcontent方法,【待修改点】变成【2】,则证明成功调用java原生方法。
android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)_第5张图片
android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)_第6张图片

5.部分源码

1)拦截js点击跳转关键代码类:

public class ClickInterceptionActivity extends Activity {

    private TextView title_name;

    private ProgressBar webview_progressbar;

    private WebView webView;

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

        initView();
        initWebViewSettings();
    }


    /**
     * 初始化布局组件
     */
    private void initView() {
        title_name = (TextView) findViewById(R.id.title_name);
        webview_progressbar = (ProgressBar) findViewById(R.id.webview_progressbar);
        webView = (WebView) findViewById(R.id.webview);

    }

    /**
     * 初始化webview配置
     */
    private void initWebViewSettings() {
        WebViewSettings.initWebSettings(webView);
        webView.setWebViewClient(new WebViewClient() {

            //返回值:true 不会显示网页资源,需要等待你的处理,false 就认为系统没有做处理,会显示网页资源
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //当url里面包含webview字段的时候,则跳转到ShowActivity原生页面,否则还是继续显示网页
                //比如:在百度输入框里面输入webview在点击搜索,再点击任何有webview字段的链接,
                //则不继续显示网页,而是跳转到自己定义的原生页面
                if (!TextUtils.isEmpty(url)
                        && url.contains("webview")) {
                    Intent intent = new Intent(ClickInterceptionActivity.this, ShowActivity.class);
                    intent.putExtra("url", url);
                    startActivity(intent);
                    finish();
                    return true;
                }
                return false;
            }

            //在页面开始加载时候做一些操作,比如展示进度条
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                webview_progressbar.setVisibility(View.VISIBLE);
                super.onPageStarted(view, url, favicon);
            }
            //在页面加载完成的时候做一些操作,比如隐藏进度条
            @Override
            public void onPageFinished(WebView view, String url) {
                webview_progressbar.setVisibility(View.GONE);
                super.onPageFinished(view, url);
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                webview_progressbar.setProgress(newProgress);
                super.onProgressChanged(view, newProgress);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                title_name.setText(title);
                super.onReceivedTitle(view, title);
            }

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
            }

        });
        webView.loadUrl("http://www.baidu.com/");
    }

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

2)js跟java交互关键类:

public class IntermodulationActivity extends Activity {

    private TextView title_name;

    private ProgressBar webview_progressbar;

    private WebView webView;

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

        initView();
        initWebViewSettings();
    }


    /**
     * 初始化布局组件
     */
    private void initView() {
        title_name = (TextView) findViewById(R.id.title_name);
        webview_progressbar = (ProgressBar) findViewById(R.id.webview_progressbar);
        webView = (WebView) findViewById(R.id.webview);

        title_name.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //调用js方法
                webView.loadUrl("javascript:setcontent(2)");
            }
        });
    }

    /**
     * 初始化webview配置
     */
    private void initWebViewSettings() {
        WebViewSettings.initWebSettings(webView);
        webView.addJavascriptInterface(new clickOnJS(), "click");
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (!TextUtils.isEmpty(url)
                        && url.contains("webview")) {
                    Intent intent = new Intent(IntermodulationActivity.this, ShowActivity.class);
                    intent.putExtra("url", url);
                    startActivity(intent);
                }
                return false;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                webview_progressbar.setVisibility(View.VISIBLE);
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                webview_progressbar.setVisibility(View.GONE);
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                webview_progressbar.setProgress(newProgress);
                super.onProgressChanged(view, newProgress);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                title_name.setText(title);
                super.onReceivedTitle(view, title);
            }

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
            }

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

    class clickOnJS {
        @JavascriptInterface
        public void OnClick() {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Toast.makeText(IntermodulationActivity.this, "调用java成功", Toast.LENGTH_SHORT).show();
        }

    }

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

3)js实现类:




    
    
    js和java交互(点击,点击)
    
    




java修改js============== 待修改点
js调用java

6.demo下载地址:

WebView demo


如有错误欢迎指出来,一起学习。

交流讨论群
群号:469890293


关注我的公众号,更多优质文章将通过公众号推送。
微信扫一扫下方二维码即可关注:
android webview一篇文章全面了解(基本使用,url拦截,js跟java交互)_第7张图片

你可能感兴趣的:(android基础知识)