zoukankan      html  css  js  c++  java
  • Android中WebView使用全解

    开始

    在Android系统中内嵌的WebKit,这是一个浏览器内核,它帮助着我们可以浏览网页。在实际开发中,如果你想让你的App能够访问网页,那就需要用到WebView这个控件。

    如何使用?

    其实使用起来很简单,通常情况下我们会在布局XML中写入这个控件之后在Activity中进行调用:

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:id="@+id/web">

    Activity/Fragment中:

    WebView webView = (WebView) findViewById(R.id.web);

    webView.loadUrl("https://lovelyyakir.github.io");

    运行一下就能看到这样的效果:


    1-1

    使用进阶

    webView的跳转和返回

    在实际使用中你会发现,有时候我们需要点击网页中的某个链接进行网页跳转,而系统会默认加载自带浏览器,而不是我们的WebView。如果你想要让WebView跳转那又该怎么做呢?

    其实很简单,我们只需要给WebView设置一个webClient,并且重写里面的shouldOverrideUrlLoading()就能很简单的实现啦。

    webView.setWebViewClient(new WebViewClient(){

    @Override

    public boolean shouldOverrideUrlLoading(WebView view, String url) {

    view.loadUrl(url);

    return true;

    }

    });

    谷歌工程师给我们提供了两个参数,我们需要调用load方法传入url,并且需要在返回值中返回true。允许在本WebView中进行跳转。当我们点击返回,你会发现程序退出了。当然这不是

    我们想要的结果。所以我们需要在Activity中重写onKeyDown(),进行判断,当我们的页面可以返回时点击返回,返回上一个界面,无法返回执行其他操作或者退出。

    @Override

    public boolean onKeyDown(int keyCode, KeyEvent event) {

    if (webView.canGoBack()&&keyCode==KeyEvent.KEYCODE_BACK) {

    webView.goBack();

    return true;

    }

    return super.onKeyDown(keyCode,event);

    }

    便是这个效果:


    1-2

    强制关闭某个Web界面

    在Native与H5交互完成的情况之下,我们需要主动关闭当前的WebView回到原生界面,这时候又该如何处理呢?其实解决途径有很多这里介绍两种解决方法:

    1.我们可以监听到最后的网页的Url获取Url之后通过字符串匹配的方式关闭当前界面,你可以在WebClient中重写下面这个方法,将跳转的URL取出来。

    @Override

    public voidonLoadResource(WebViewview,Stringurl){

    //监听到进入了关闭页面就把activity关闭

    LogUtil.e("跳转的url:"+url);

    }

    通过匹配字符串做相应的操作。

    2.通过控制台获取相关的信息,根据信息做相应操作。

    webView.setWebChromeClient(newWebChromeClient(){

    @Override

    public boolean onConsoleMessage(ConsoleMessageconsole Message){

    LogUtil.e(consoleMessage.message());

    if("success".equals(consoleMessage.message())||"close window".equals(consoleMessage.message())){

    finish();

    }

    return super.onConsoleMessage(consoleMessage);

    }

    });

    通过WebView的setChromClient重写onConsoleMessage通过相关的信息做相应的操作。

    进阶操作

    WebView与Javascript进行交互

    在实际开发中,调用webview,我们希望能与其他其他网页进行交互。非原生界面调用原生方法,原生界面调用非原生方法。(WebView与Javascript相互调用)。

    1.Javascript调用Java原生代码

    我们先看一段Javascript的代码:

    $("#test1").click(function(e){window.injs.takeFrontIDCardCamera();});

    $("#test2").click(function(e){window.injs.takeBackIDCardCamera();});

    $("#test3").click(function(e){window.injs.takeFaceCamera();});

    这里表示三个Javascript点击事件,window.injs.takeFaceCamera();这行代码中window表示窗口,injs表示作用域,紧跟着的就是方法名了。我们需要让WebView允许和Javascript进行交互,并且绑定作用域。

    webView.getSettings().setJavaScriptEnabled(true);

    webView.addJavascriptInterface(this,"injs");

    最后重写Javascript方法:

    @JavascriptInterface

    public void takeFrontIDCardCamera() {

    Toast.makeText(this,"Native get takeFrontIDCardCamera",Toast.LENGTH_SHORT).show();

    }

    @JavascriptInterface

    public void takeBackIDCardCamera() {

    Toast.makeText(this,"Native get takeBackIDCardCamera",Toast.LENGTH_SHORT).show();

    }

    @JavascriptInterface

    public void takeFaceCamera() {

    Toast.makeText(this,"Native get takeFaceCamera",Toast.LENGTH_SHORT).show();

    }

    Javascript调用原生方法时弹出一个土司验证


    1-3

    2.原生界面调用Javascript

    下面展示几个Javascript本地方法

    function  jhjcardfontjs(font){

    alert(font);

    }

    function  jhjcardbackjs(back){

    alert(back);

    }

    function jhjfacejs(face){

    alert(face);

    }

    调用无参的方法时只需要在webview的load方法中写入javascript:你的方法()。像这样:

    webView.loadUrl("javascript:jhjcardfontjs()");

    如果有参数要注意,脚本中会有转义符需要处理一下再传入:

    String var="";

    var=var.replaceAll("\\", "\\\\");

    webView.loadUrl("javascript:jhjcardfontjs('" + var + "')");

    登陆Session同步

    用户通过原生App进行登录,之后进行某些操作到H5界面,这个时候原生界面和H5界面的登陆状态不同,为了防止用户再次登陆造成的用户体验问题,我们需要让WebView同步我们原声界面的Session让用户不用重新登陆。

    1.获取用户登录信息Cookie,你可以通过你使用的网络请求框架获取Cookie。这里我使用OkHttp获取我的Cookie信息,之后将这个信息保存起来:

    Listcookies=OkHttpUtils

    .getInstance()

    .getOkHttpClient()

    .cookieJar()

    .loadForRequest(HttpUrl.parse(SysConfig.myFinalUrl(SysConfig.loginUrl)));

    for(Cookiecookie:cookies){

    //保存在内存当中

    if(!cookie.value().contains("dk")){

    Constant.appCookie=cookie;

    }

    }

    2.在WebView中加载他:

    CookiesessionCookie=Constant.appCookie;//这里的cookie就是上面保存的cookie

    CookieSyncManager.createInstance(this);

    CookieManagercookieManager=CookieManager.getInstance();

    if(sessionCookie!=null){

    cookieManager.removeSessionCookie();

    StringcookieString=sessionCookie.name()+"="+sessionCookie.

    value()+"; domain="+sessionCookie.domain();

    cookieManager.setCookie(sessionCookie.domain(),cookieString);

    CookieSyncManager.getInstance().sync();

    wbQrContent.setWebViewClient(newWebViewClient(){

    @Override

    public booleanshouldOverrideUrlLoading(WebViewview,Stringurl){

    view.loadUrl(url);

    return true;

    }

    });

    }

    补充

    1.WebViewClient和WebChromeClient有什么不同?

    WebViewClient主要帮助WebView处理各种通知、请求事件而如果你想处理js、进度条等,就要用到WebChromeClient。他们的区别在于功能的区别。

    2.为什么我调用JS修改原生UI报错了?

    如果你在JavaScript中调用原生方法修改Ui,你需要确保这个方法执行在主线程。这是由于JavaBridge并不在主线程中。(你可以使用hander,runOnUiThread,Rxjava)

  • 相关阅读:
    群辉:服务器错误 错误代码38
    wireshark filter manualpage
    收集下shell使用笔记
    Android kernel LOGO的更换方法
    java实现截屏
    [转]android4.0.3 修改启动动画和开机声音
    博客搬迁
    idea 2017.3创建springboot项目报无效的源发行版: 1.8或者Unsupported major.minor version 52.0的解决方案
    关于mybatis查询集合返回为[null]的问题
    关于mybatis中resultType返回null的问题
  • 原文地址:https://www.cnblogs.com/lovelyYakir/p/7125216.html
Copyright © 2011-2022 走看看