安卓系统webview 是什么来的

发布网友 发布时间:2022-04-22 06:24

我来回答

5个回答

懂视网 时间:2022-05-04 01:58

引子 web?native?这是个争论了很久的问题。 自从微信开放了更多的JS接口之后,移动web开发重新火了起来,前端程序猿也水涨船高。 毫无疑问,web页面有诸多优点: 跨平台:一次开发,可以同时在Android,iOS和Other Phone上运行(美好的愿望) 快速迭代,内容

引子

web?native?这是个争论了很久的问题。
自从微信开放了更多的JS接口之后,移动web开发重新火了起来,前端程序猿也水涨船高。

毫无疑问,web页面有诸多优点:

  • 跨平台:一次开发,可以同时在Android,iOS和Other Phone上运行(美好的愿望)

  • 快速迭代,内容统一:内容修改后,不同版本都能展示最新内容。可以避免频繁的客户端升级,也无需经过App Store的审核

  • 语言优势:庞大JavaScript开发人员,能够带来移动端内容的繁荣

  • 本人多年开发研究web与native混合APP,因为这里面有很多的坑,很有必要把经验归纳一番。

    准备

    区分APP和浏览器

    我们的web页面是通过哪个应用打开的呢?这是要解决的第一个问题,这样才能做到APP与系统浏览器的内容差异化。

  • 通过域名
    将不同用途的页面归类到不同服务器或Web项目下,这是最简单也最笨的方法,如果同一个页面要在三端上都展示,那么就要复制3份了

  • 通过元数据

  • 通过UA标识
    这是web页面统计访问终端的品牌和分辨率的常用方法
    我会在WebView的默认UA后面,加上自定义的标识,包括APP的标识 (AndroidApp、iPhoneApp)、应用包名和APP的版本号
    判断是否微信浏览器就可以使用这个方法,同时最好检查是否加载了微信自定义的weixin.js文件

  • 配置WebView基础参数

    final WebSettings settings = getSettings();// 允许JS弹出提示框settings.setJavaScriptCanOpenWindowsAutomatically(true);// 允许web执行JSsettings.setJavaScriptEnabled(true);// 设置浏览器标识settings.setUserAgentString(buildAppUserAgent(getContext(), settings.getUserAgentString()));// 是否支持缩放,默认不支持(看起来更native)settings.setSupportZoom(false);
    settings.setBuiltInZoomControls(false);// 打开H5的离线缓存settings.setAppCacheEnabled(true);final String cachedir = getContext().getDir("cache", Context.MODE_PRIVATE).getPath();
    settings.setAppCachePath(cachedir);// 打开H5的Dom Storage(localStorage,sessionStorage)settings.setDomStorageEnabled(true);// 如果要使用离线缓存和DomStorage必须要设置web databasefinal String dbdir = getContext().getDir("database", Context.MODE_PRIVATE).getPath();
    settings.setDatabaseEnabled(true);
    settings.setDatabasePath(dbdir);

    WebViewClient对象

    监听页面加载情况(开始加载、资源加载、完成加载、页面错误)

    通常情况下,我们都会有一个loading界面覆盖在webview上面,当页面加载完成隐藏loading。
    这里存在2个小问题:

  • webview只有当所有内容都加载完成后,才会回调onPageFinished。
    也就是说,当DOM元素加载完成,并且所有图片也加载完成才会触发,这对于追求体验的移动APP来说,显然无法接受。尤其是当网络不好或图片太大时尤为明显,用户看到的是明明页面已经基本出来了,却仍然在loading,无法操作。
    其实JS端可以监听到DOMContentLoaded事件,此时是关闭loading的最佳时机

  • 出现加载错误时,不仅会调用onReceivedError,仍然会调用onPageFinished
    有些人喜欢把loading界面和error界面写在同一个layout里,出现错误时显示error,完成加载时隐藏整个layout。
    这对于普通页面来说没有问题,但是对于webview就会出现error无法被显示的情况。
    所以最后将loading和error分开,在onPageFinished时,只需要隐藏loading部分。

  • 拦截页面链接

    重写shouldOverrideUrlLoading方法,当返回值为true时,需要自己处理url请求,webview将不会插手。
    此方法只在涉及页面跳转时被触发。
    这里存在2个问题:

  • 低版本的某些请求不会触发此方法,直接在本webview打开了新页面。
    如果想拦截,则需要在onPageStarted方法里判断url是否已经改变,更改了的话就表明打开了新的链接。

  • 页面重定向无法识别
    当页面存在重定向时,API并没有提供方法作区分,这时需要自己处理。

  • 替换加载内容

    重写shouldInterceptRequest方法,可以替换JS、CSS、img等内容。
    创建WebResourceResponse对象,并传入文件输入流,即可用其他资源替换本来要加载的内容。
    通过此方法,我们可以预先下载页面所需的JS和CSS文件,保存到本地;然后当打开页面时,直接使用本地已下载的文件。这样可以大幅提高页面加载速度。
    注:此方法只能API Level 11以后使用,低版本可通过ContentProvider实现类似功能。

    WebChromeClient对象

    WebViewClient类主要设计链接和资源加载的功能实现
    WebChromeClient类则会涉及更底层的内容,如控制台调试、JS弹出框、显示自定义view等。

    替换Alert对话框

    web页面一般会通过alert方法,显示一些提示信息,但是对话框的样式却因不同的品牌差异很大,为了使我们的APP保持统一风格,有必要替换成我们自己设计的对话框。
    重写onJsAlert方法,将message显示到Dialog。
    该方法是模态的,必须返回内容才能关闭对话框,调用JsResult.cancel或者JsResult.confirm。如果只调用了Dialog.dismiss而没有调用JsResult的方法,会出现,虽然对话框消失,但是线程一直处于阻塞状态,造成假死现象,无法进行任何操作。

    全屏播放视频

    webview默认不能全屏播放,需要client端提供全屏的window。
    代码如下:

    @Override
    public void onShowCustomView (View view, WebChromeClient.CustomViewCallback callback) {
     mCustomViewCallback = callback;android.view.Window window = WebActivity.this.getWindow();window.setFlags(
      android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN,
      android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);setRequestedOrientation(android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);mTitleBar.setVisibility(View.INVISIBLE);mWebView.setVisibility(View.INVISIBLE);mExitFullscreenBtn.setVisibility(View.VISIBLE);mVideoViewContainer.setVisibility(View.VISIBLE);mVideoViewContainer.addView(view);}
    
    @Override
    public void onHideCustomView () {
     mCustomViewCallback.onCustomViewHidden();android.view.Window window = WebActivity.this.getWindow();window.setFlags(0,
      android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);setRequestedOrientation(android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);mTitleBar.setVisibility(View.VISIBLE);mWebView.setVisibility(View.VISIBLE);mExitFullscreenBtn.setVisibility(View.INVISIBLE);mVideoViewContainer.setVisibility(View.INVISIBLE);mVideoViewContainer.removeAllViews();}

    Cookie

    如果web端需要用户登录的操作,那么就涉及到native和web端同步登录状态,这就需要用到cookie。

    // 打开Cookie支持CookieSyncManager.createInstance(this);
    CookieManager cookieManager = CookieManager.getInstance();
    cookieManager.setAcceptCookie(true);
    // 设置cookie
    sBuff.append(key).append("=").append(value);sBuff.append("; path=/");sBuff.append("; domain=").append(domain);cookieManager.setCookie(url, sBuff.toString());......
    CookieSyncManager.getInstance().sync();
    // 删除cookie// 清除过期的cookiecookieManager.removeExpiredCookie();// 清除所有cookiecookieManager.removeAllCookie();

    因为并不存在单独删除cookie的某个字段的方法,所有要清除某个字段,要先将其设为已过期,再调用removeExpiredCookie

    如何同步登录状态

    简单的情况,只需要有userid即可认为已经登录,分如下两种情况:
    - 先从native登录
    native端调用登录接口,拿到useid后,当需要打开web时,在loadUrl之前,将userid保存到cookie中,服务端就会从cookie中读出userid。
    - 先从web端登录
    web登录后,webview会自动保存cookie。web端需要与native端定义接口,将username和userid通知给native端,native保存起来。

    Web端与Native端互相通讯

    WebView调用web端JS方法

    mWebView.loadUrl("javascript:JSMethod()");

    API 19以后,提供了更加便捷的方法,可以直接获取JS的返回值。(iOS本身已经提供类似API)

    WebView.evaluateJavascript (String script, ValueCallback<String> resultCallback)

    web端调用native代码

    早期API提供的方法:

    WebView.addJavascriptInterface(Object object, String name)
    WebView会将object注入到web端的window对象中,name是object对象定义的方法,web端通过object.name即可调用native端的功能。

    but,这个方法存在安全漏洞 漏洞详细说明
    如果你的targetSdkVersion>=17,那么必须将java方法加上注解@JavascriptInterface,否则web端是无法调用的。

    自定义scheme

    通过自定义scheme的方式,在shouldOverrideUrlLoading拦截,并定向到相应的native逻辑。
    iOS端需通过此方法实现。

    利用WebChromeClient.onJsPrompt

    因为JS端很少使用prompt(一般使用alert)方法,所以我们可以利用这个方法,通过自定义协议格式,来实现web与native端的通信。
    因为此方法需要返回JsResult对象,所以利用此机制,可以实现方法的同步调用(web端可以获取到接口方法的返回值,有利于代码和逻辑的简化)
    大名鼎鼎PhoneGap(现在叫Cordova)就是利用此方法实现的web与native通讯。

    我会专门写一篇,我是如何实现web与native通信的。

    其他技巧

    屏蔽长按事件

    重写performLongClick
    或者setOnLongClickListener实现空的listener

    隐藏选择框

    可以使用全局的一个CSS
    *{-webkit-tap-highlight-color: rgba(0, 0, 0, 0);}

    缩放按钮引起的崩溃

    在某些机型上,当显示webview的缩放按钮时,退出Activity,就会报如下错误:

    android.view.WindowLeaked: Activity com.secoo.activity.web.WebActivity has leaked window android.widget.ZoomButtonsController$Container{438e8248 V.E..... ........ 0,0-1536,194} that was originally added here
     at android.view.ViewRootImpl.(ViewRootImpl.java:382)
     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:261)
     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:76)
     at android.widget.ZoomButtonsController.setVisible(ZoomButtonsController.java:371)
     ......

    这是因为按钮的隐藏是延迟触发,在activity退出之后,造成了window的泄露。

    解决方法:

    // API 11之后,不显示缩放按钮
    WebView.getSettings().setDisplayZoomControls(false);// API 11之前,在finish时,从view层级中删除webview
    ViewGroup viewgroup = (ViewGroup)(mWebView.getParent());viewgroup.removeView(mWebView);

    技术交流请留言…
    To Be Continue…

    热心网友 时间:2022-05-03 23:06

    WebView是用于展示网络请求后的结果,也就是将url网络请求的结果展示在里面。

    WebView是一个基于webkit引擎、展现web页面的控件。Android的Webview在低版本和高版本采用了不同的webkit版本内核,Android4.4后直接使用了Chrome。

    WebView的作用:

    1.显示和渲染Web页面;

    2.直接使用html文件(网络上或本地assets中)作布局;

    3.可和JavaScript交互调用。

    扩展资料:

    WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。一般来说Webview可单独使用,也可联合其工具类一起使用。

    移动应用的主体是WebView,主要以网页语言编写,穿插Native功能的Hybrid App开发类型。激活WebView为活跃状态,能正常执行网页的响应。

    当WebView的页面被失去焦点被切换到后台不可见状态,需要执行onPause。通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。

    参考资料来源:百度百科—hybrid app

    热心网友 时间:2022-05-04 00:24

    WebKit是Mac OS X v10.3及以上版本所包含的软件框架(对v10.2.7及以上版本也可通过软件更新获取)。 同时,WebKit也是Mac OS
    X的Safari网页浏览器的基础。WebKit是一个开源项目,主要由KDE的KHTML修改而来并且包含了一些来自苹果公司的一些组件。

    传统上,WebKit包含一个网页引擎WebCore和一个脚本引擎JavaScriptCore,它们分别对应的是KDE的KHTML和KJS。不过,
    随着JavaScript引擎的性越来越强,现在WebKit和WebCore已经基本上混用不分(例如Google Chrome和Maxthon
    3采用V8引擎,却仍然宣称自己是WebKit内核)。

    Androidsystemwebview应该是一浏览器控件可以卸载,卸载方式:

    打开主菜单选择设置在设置中选择应用选择你需要停止的应用,例如Mediacode等点击强行停止,同时可能会弹出一个警告,点确定即可确定完成就可以彻底停止这个应用运行了点击卸载即可卸载这个应用建议不要卸载,Android系统设置中如果强制停止某些应用,可能会造成程序出错,闪退,死机,重启等后果,不过某些应用不给退出的情况下只能用这种方式

    热心网友 时间:2022-05-04 01:59

    WebView(网络视图)能加载显示网页,可以将其视为一个浏览器。它使用了WebKit渲染引擎加载显示网页,实现WebView有以下两种不同的方法:
    第一种方法的步骤:
    1.在要Activity中实例化WebView组件:WebView webView = new WebView(this);
    2.调用WebView的loadUrl()方法,设置WevView要显示的网页:
    互联网用:webView.loadUrl("http://www.google.com");
    本地文件用:webView.loadUrl("file:///android_asset/XX.html"); 本地文件存放在:assets 文件中
    3.调用Activity的setContentView( )方法来显示网页视图
    4.用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面
    5.需要在AndroidManifest.xml文件中添加权限,否则会出现Web page not available错误。

    第二种方法的步骤:
    1、在布局文件中声明WebView
    2、在Activity中实例化WebView
    3、调用WebView的loadUrl( )方法,设置WevView要显示的网页
    4、为了让WebView能够响应超链接功能,调用setWebViewClient( )方法,设置 WebView视图
    5、用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面
    6、需要在AndroidManifest.xml文件中添加权限,否则出现Web page not available错误。

    热心网友 时间:2022-05-04 03:50

    webView是用于展示网络请求后的结果,举个例子:你自己写了个APP,你想要用它访问网络,这里假设你要访问百度首页,你不想用手机的自带浏览器,而是想要用你自己的app在内部展示百度网页,那么就可以用webView啦
    说白了:webView就是将url网络请求的结果展示在里面

    声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com