转自: https://www.cnblogs.com/sanchang/p/9261461.html

一 WebView到底是什么

    1 WebView是一种控件,它基于webkit引擎,因此具备渲染Web页面的功能。  

  2 基于Webview的混合开发,就是在 Anddroid os(安卓)/I os(苹果)原生APP里,通过WebView控件嵌入Web页面。

  你手机里有淘宝软件吧?
  就是外边是个原生APP的壳,内容是H5页面(基于html+css+js的Web页面)。

  包括淘宝app,阿里云app(笔者目前做阿里云app组件库的开发)等等在内,现在的移动端混合开发软件,如果对于交互渲染要求不是特别高的项目,基本都是这么玩的。

二 这么玩的原因 

  1. 用h5开发的内容页面,跨平台。你想想,无论你用的安卓还是苹果,你的淘宝app里都是H5页面。
   也就是一次开发,多系统适配。是不是节省了人力成本和时间成本?
   如果不用混合开发这种方式,就得找安卓工程师开发安卓端的,苹果ios工程师开发苹果的,需要开发两次——是不是很麻烦并且老板多出一倍工资啊……

  2. Web更新方式为线上即时更新,不用下载安装补丁包
   你想想,你玩王者或吃鸡吗?这些游戏里的游戏内容无疑都是原生开发的,每次更新你都得先下载安装包吧?当然,打开游戏经常会有一些类似活动公告、说明公告等一些窗口,这些可能也是由WebView嵌入的Web页面。也就是说,原生app里嵌入的Web内容所占比例可大可小,根据需求,对于适合WebView的模块,我们就可以选择用WebView实现它。
   
而WebView中嵌入的网页更新需要下载包吗?——更新后的内容即时上线,根本不需要。

     这样对于用户来讲就很舒服啊。

  

  3. H5性能不断提高。
  实际上,h5页面的交互、渲染性能肯定是比不上原生的——
  
但是,h5技术进步快,加上4g网络的普及化(5g时代马上也来了),性能这一块就逐渐不再成问题了——典型的案例就是电商类app,性能差距基本看不出来,用户还是很舒服滴。

  当然,像游戏啥的,牵扯到渲染引擎性能的问题,对于这点,Web渲染引擎还是非常勉强的。
  
——因为性能比起安卓原生或ios原生来讲,太差。

  

  你可以参考网页游戏和客户端游戏的区别——一种代表是一刀999级的贪玩蓝月!一种是你玩过的飞车啊炫舞啊诛仙啊……(听说现在逆水寒挺火的)。
  都是游戏,差距是不是有点大。

三 WebView具体怎么玩

  转自: https://blog.csdn.net/qq_36252044/article/details/77993297

  WebView的使用详解

  1.简介

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

2.作用

  • 显示和渲染Web页面
  • 直接使用html文件(网络上或本地assets中)作布局
  • 可和JavaScript交互调用

WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求、页面加载、渲染、页面交互进行强大的处理。

3.使用介绍

一般来说Webview可单独使用,可联合其子类一起使用,下面会介绍几种:

  • Webview自身的常见方法;
  • Webview的最常用的子类 
    (WebSettings类、WebViewClient类、WebChromeClient类)
  • Android和Js的交互

3.1 Webview常用方法

3.1.1 加载URL

可以根据资源分为三种:

//方式1. 加载一个网页: 
webView.loadUrl(“http://www.baidu.com/“);

//方式2:加载apk包中的html页面 
webView.loadUrl(“file:///android_asset/test.html”);

//方式3:加载手机本地的html页面 
webView.loadUrl(“content://com.android.htmlfileprovider/sdcard/test.html”);

// 方式4: 加载 HTML 页面的一小段内容 
WebView.loadData(String data, String mimeType, String encoding) 
// 参数说明: 
// 参数1:需要截取展示的内容 
// 内容里不能出现 ’#’, ‘%’, ‘\’ , ‘?’ 这四个字符,若出现了需用 %23, %25, %27, %3f 对应来替代,否则会出现异常 
// 参数2:展示内容的类型 
// 参数3:字节码

3.1.2 WebView的状态

//激活WebView为活跃状态,能正常执行网页的响应 
webView.onResume() ;

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

//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview 
//它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。 
webView.pauseTimers() 
//恢复pauseTimers状态 
webView.resumeTimers();

//销毁Webview 
//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview 
//但是注意:webview调用destory时,webview仍绑定在Activity上 
//这是由于自定义webview构建时传入了该Activity的context对象 
//因此需要先从父容器中移除webview,然后再销毁webview: 
rootLayout.removeView(webView); 
webView.destroy();

3.1.2 关于前进 / 后退网页

//是否可以后退 
Webview.canGoBack() 
//后退网页 
Webview.goBack()

//是否可以前进 
Webview.canGoForward() 
//前进网页 
Webview.goForward()

//以当前的index为起始点前进或者后退到历史记录中指定的steps 
//如果steps为负数则为后退,正数则为前进 
Webview.goBackOrForward(intsteps)

常见用法:Back键控制网页后退

  • 问题:在不做任何处理前提下 ,浏览网页时点击系统的“Back”键,整个 Browser 会调用 finish()而结束自身
  • 目标:点击返回后,是网页回退而不是推出浏览器
  • 解决方案:在当前Activity中处理并消费掉该 Back 事件 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) { 
    mWebView.goBack(); 
    return true; 

    return super.onKeyDown(keyCode, event); 
    }

3.1.3 清除缓存数据

//清除网页访问留下的缓存 
//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序. 
Webview.clearCache(true);

//清除当前webview访问的历史记录 
//只会webview访问历史记录里的所有记录除了当前访问记录 
Webview.clearHistory();

//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据 
Webview.clearFormData();

3.2 常用类

3.2.1 WebSettings类

 * 作用:对WebView进行配置和管理
* 配置步骤 & 常见方法:

配置步骤1:添加访问网络权限(AndroidManifest.xml) 
这是前提!这是前提!这是前提!

配置步骤2:生成一个WebView组件(有两种方式)

//方式1:直接在在Activity中生成 
WebView webView = new WebView(this)

//方法2:在Activity的layout文件里添加webview控件: 
WebView webview = (WebView) findViewById(R.id.webView1); 
配置步骤3:进行配置-利用WebSettings子类(常见方法) 
//声明WebSettings子类 
WebSettings webSettings = webView.getSettings();

//如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript 
webSettings.setJavaScriptEnabled(true); 
// 若加载的 html 里有JS 在执行动画等操作,会造成资源浪费(CPU、电量) 
// 在 onStop 和 onResume 里分别把 setJavaScriptEnabled() 给设置成 false 和 true 即可

//支持插件 
webSettings.setPluginsEnabled(true);

//设置自适应屏幕,两者合用 
webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小 
webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

//缩放操作 
webSettings.setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。 
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放 
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

//其他细节操作 
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存 
webSettings.setAllowFileAccess(true); //设置可以访问文件 
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口 
webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片 
webSettings.setDefaultTextEncodingName(“utf-8”);//设置编码格式

常见用法:设置WebView缓存

 * 当加载 html 页面时,WebView会在/data/data/包名目录下生成 database 与 cache 两个文件夹
* 请求的 URL记录保存在 WebViewCache.db,而 URL的内容是保存在 WebViewCache 文件夹下
* 是否启用缓存:

//优先使用缓存: 
WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 
//缓存模式如下: 
//LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据 
//LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。 
//LOAD_NO_CACHE: 不使用缓存,只从网络获取数据. 
//LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。

//不使用缓存: 
WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); 
* 结合使用(离线加载)

if (NetStatusUtil.isConnected(getApplicationContext())) { 
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根据cache-control决定是否从网络上取数据。 
} else { 
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//没网,则从本地获取,即离线加载 
}

webSettings.setDomStorageEnabled(true); // 开启 DOM storage API 功能 
webSettings.setDatabaseEnabled(true); //开启 database storage API 功能 
webSettings.setAppCacheEnabled(true);//开启 Application Caches 功能

String cacheDirPath = getFilesDir().getAbsolutePath() + APP_CACAHE_DIRNAME; 
webSettings.setAppCachePath(cacheDirPath); //设置 Application Caches 缓存目录 
注意: 每个 Application 只调用一次 WebSettings.setAppCachePath(),WebSettings.setAppCacheMaxSize()

3.2.2 WebViewClient类

 * 作用:处理各种通知 & 请求事件
* 常见方法:

常见方法1:shouldOverrideUrlLoading()

* 作用:打开网页时不调用系统浏览器, 而是在本WebView中显示;在网页上的所有加载都经过这个方法,这个函数我们可以做很多操作。

//步骤1. 定义Webview组件 
Webview webview = (WebView) findViewById(R.id.webView1);

//步骤2. 选择加载方式 
//方式1. 加载一个网页: 
webView.loadUrl(“http://www.google.com/“);

//方式2:加载apk包中的html页面 
webView.loadUrl(“file:///android_asset/test.html”);

//方式3:加载手机本地的html页面 
webView.loadUrl(“content://com.android.htmlfileprovider/sdcard/test.html”);

//步骤3. 复写shouldOverrideUrlLoading()方法,使得打开网页时不调用系统浏览器, 而是在本WebView中显示 
webView.setWebViewClient(new WebViewClient(){ 
@Override 
public boolean shouldOverrideUrlLoading(WebView view, String url) { 
view.loadUrl(url); 
return true; 

}); 
常见方法2:onPageStarted()

* 作用:开始载入页面调用的,我们可以设定一个loading的页面,告诉用户程序在等待网络响应。

webView.setWebViewClient(new WebViewClient(){ 
@Override 
public void onPageStarted(WebView view, String url, Bitmap favicon) { 
//设定加载开始的操作 

});

常见方法3:onPageFinished()

 * 作用:在页面加载结束时调用。我们可以关闭loading 条,切换程序动作。

webView.setWebViewClient(new WebViewClient(){ 
@Override 
public void onPageFinished(WebView view, String url) { 
//设定加载结束的操作 

});

常见方法4:onLoadResource()

* 作用:在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次。

webView.setWebViewClient(new WebViewClient(){ 
@Override 
public boolean onLoadResource(WebView view, String url) { 
//设定加载资源的操作 

});

常见方法5:onReceivedError()

 * 作用:加载页面的服务器出现错误时(如404)调用。

App里面使用webview控件的时候遇到了诸如404这类的错误的时候,若也显示浏览器里面的那种错误提示页面就显得很丑陋了,那么这个时候我们的app就需要加载一个本地的错误提示页面,即webview如何加载一个本地的页面

//步骤1:写一个html文件(error_handle.html),用于出错时展示给用户看的提示页面 
//步骤2:将该html文件放置到代码根目录的assets文件夹下

//步骤3:复写WebViewClient的onRecievedError方法 
//该方法传回了错误码,根据错误类型可以进行不同的错误分类处理 
webView.setWebViewClient(new WebViewClient(){ 
@Override 
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){ 
switch(errorCode) 

case HttpStatus.SC_NOT_FOUND: 
view.loadUrl(“file:///android_assets/error_handle.html”); 
break; 


}); 
常见方法6:onReceivedSslError()

  作用:处理https请求

webView默认是不处理https请求的,页面显示空白,需要进行如下设置:

webView.setWebViewClient(new WebViewClient() { 
@Override 
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) { 
handler.proceed(); //表示等待证书响应 
// handler.cancel(); //表示挂起连接,为默认方式 
// handler.handleMessage(null); //可做其他处理 

});

3.2.3 WebChromeClient类

* 作用:辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等等。
* 常见使用:

常见方法1: onProgressChanged()

 * 作用:获得网页的加载进度并显示

webview.setWebChromeClient(new WebChromeClient(){

@Override 
public void onProgressChanged(WebView view, int newProgress) { 
if (newProgress < 100) { 
String progress = newProgress + “%”; 
progress.setText(progress); 
} else { 

});

常见方法2: onReceivedTitle()

 * 作用:获取Web页中的标题

每个网页的页面都有一个标题,比如www.baidu.com这个页面的标题即“百度一下,你就知道”,那么如何知道当前webview正在加载的页面的title并进行设置呢?

webview.setWebChromeClient(new WebChromeClient(){

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

常见方法3: onJsAlert()

* 作用:支持javascript的警告框

一般情况下在 Android 中为 Toast,在文本里面加入\n就可以换行

webview.setWebChromeClient(new WebChromeClient() {

@Override 
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) { 
new AlertDialog.Builder(MainActivity.this) 
.setTitle(“JsAlert”) 
.setMessage(message) 
.setPositiveButton(“OK”, new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialog, int which) { 
result.confirm(); 

}) 
.setCancelable(false) 
.show(); 
return true; 

常见方法4: onJsConfirm()

 * 作用:支持javascript的确认框

webview.setWebChromeClient(new WebChromeClient() {

@Override 
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) { 
new AlertDialog.Builder(MainActivity.this) 
.setTitle(“JsConfirm”) 
.setMessage(message) 
.setPositiveButton(“OK”, new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialog, int which) { 
result.confirm(); 

}) 
.setNegativeButton(“Cancel”, new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialog, int which) { 
result.cancel(); 

}) 
.setCancelable(false) 
.show(); 
// 返回布尔值:判断点击时确认还是取消 
// true表示点击了确认;false表示点击了取消; 
return true; 

常见方法5: onJsPrompt()

* 作用:支持javascript输入框

点击确认返回输入框中的值,点击取消返回 null。

webview.setWebChromeClient(new WebChromeClient() { 
@Override 
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) { 
final EditText et = new EditText(MainActivity.this); 
et.setText(defaultValue); 
new AlertDialog.Builder(MainActivity.this) 
.setTitle(message) 
.setView(et) 
.setPositiveButton(“OK”, new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialog, int which) { 
result.confirm(et.getText().toString()); 

}) 
.setNegativeButton(“Cancel”, new DialogInterface.OnClickListener() { 
@Override 
public void onClick(DialogInterface dialog, int which) { 
result.cancel(); 

}) 
.setCancelable(false) 
.show();

return true; 
}

3.3 WebView与JavaScript的交互

3.4 注意事项:如何避免WebView内存泄露?

3.4.1 不在xml中定义 Webview ,而是在需要的时候在Activity中创建,并且Context使用 getApplicationgContext()

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); 
mWebView = new WebView(getApplicationContext()); 
mWebView.setLayoutParams(params); 
mLayout.addView(mWebView);

3.4.2 在 Activity 销毁( WebView )的时候,先让 WebView 加载null内容,然后移除 WebView,再销毁 WebView,最后置空。

@Override 
protected void onDestroy() { 
if (mWebView != null) { 
mWebView.loadDataWithBaseURL(null, “”, “text/html”, “utf-8”, null); 
mWebView.clearHistory();

((ViewGroup) mWebView.getParent()).removeView(mWebView); 
mWebView.destroy(); 
mWebView = null; 

super.onDestroy(); 
}

最新文章

  1. Navicat备份远程Oracle数据库到本地
  2. Nutch源码阅读进程5---updatedb
  3. Bash Shell read file line by line and substring
  4. Lucene 4.7 --高亮显示
  5. Moogoose操作之Schema实现增删查改
  6. 关于header跳转之后的乱码问题
  7. Eclipse里面开发ExtJS程序
  8. chmod u+x ./j2sdk-1_4_2_04-linux-i586.bin的含义
  9. Delphi RichEx 图像
  10. 逐行返回http响应的内容
  11. Oracle EBS-SQL (INV-7):检查接收中记录数.sql
  12. Zabbix实战-简易教程--技巧一(操作类技巧)
  13. 图片转web字体库,如何制作web字体库
  14. css中的数学表达式calc()
  15. javascript方法篇-String
  16. UML类图应该怎么看?
  17. cmd强行终止进程
  18. 基于TcpListerer的web服务器 和 基于HttpListerer的web服务器
  19. python flask实现小项目方法
  20. C# 线程:定时器的使用

热门文章

  1. layUI框架中文件上传前后端交互及遇到的相关问题
  2. Java开发笔记(八十六)通过缓冲区读写文件
  3. oracle学习笔记(四) DQL数据查询语言和TCL 事务控制语言
  4. 【Android】用Cubism 2制作自己的Live2D——android sdk样本的下载与Android studio编译!
  5. 【Android】用Cubism 2制作自己的Live2D——官方App样例源码学习(4)!
  6. SQL Server 取日期时间格式 日期与字符串之间的转换
  7. 查看Eclipse版本号及各个版本区别
  8. gradle下载及配置
  9. 芒果绿的blog
  10. Vue 2.6版本基础知识概要(一)