android webview 面试

总结

参考:https://www.jianshu.com/p/fd61e8f4049e

内核版本比较:https://www.cnblogs.com/gcczhongduan/p/4237959.html

x5 和 原生 比较:https://www.jianshu.com/p/d27f3379a4b7

使用心得

https://www.jianshu.com/p/3c94ae673e2a

https://www.jianshu.com/p/52ec85259ccc

1.WebView 中网页的前进 / 后退

webView.goBack();//跳到上个页面
webView.goForward();//跳到下个页面
webView.canGoBack();//是否可以跳到上一页(如果返回false,说明已经是第一页)
webView.canGoForward();//是否可以跳到下一页(如果返回false,说明已经是最后一页)
  • 常见用法: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);
}

2.webView 缓存设置

//优先使用缓存: 
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);

3.webView 清除缓存

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

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

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

另外一种方式:
//删除缓存文件夹
File file = CacheManager.getCacheFileBaseDir(); 

if (file != null && file.exists() && file.isDirectory()) { 
for (File item : file.listFiles()) { 
    item.delete(); 
     } 
    file.delete(); 
} 
        
//删除缓存数据库
context.deleteDatabase("webview.db"); 
context.deleteDatabase("webviewCache.db");

4.cookies 设置,获取和清除

  • Cookie 设置

代码

CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);

String cookie = "name=xxx;age=18";
cookieManager.setCookie(URL, cookie);
CookieSyncManager.getInstance().sync();
  • 获取 Cookie

code:

CookieManager cookieManager = CookieManager.getInstance();
String cookie = cookieManager.getCookie(URL);
  • 清除 Cookie

code

CookieSyncManager.createInstance(context);  
CookieManager cookieManager = CookieManager.getInstance(); 
cookieManager.removeAllCookie();
CookieSyncManager.getInstance().sync();

5.webview 和 js 交互

  • JavaScript 调用 Android

code

WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);//开启JavaScript 

mWebView.loadUrl("file:///android_asset/keithxiaoy.html");//加载本地网页
mWebView.setWebChromeClient(new WebChromeClient());//此行代码可以保证JavaScript的Alert弹窗正常弹出

//核心方法, 用于处理JavaScript被执行后的回调
mWebView.addJavascriptInterface(new JsCallback() {

  @JavascriptInterface//注意:此处一定要加该注解,否则在4.1+系统上运行失败
  @Override
  public void onJsCallback() {
      System.out.println("JavaScript调用Android啦");
  }
}, "keithxiaoy");//参1是回调接口的实现;参2是JavaScript回调对象的名称

//定义回调接口
public interface JsCallback {
  public void onJsCallback();
}
  • Android 调用 JavaScript

code

  //直接使用webview加载js就可以了
  mWebView.loadUrl("javascript:wave()");
  • 附上 keithxiaoy.html 源码

code

 
 
 
 
 
     
     
![](android_normal.png)
Click me!

面试题

1.WebView的内存泄露。

(1)微信和qq的做法:

就是 当你要用webview的时候,记得最好 另外单独开一个进程 去使用webview 并且当这个 进程结束时,请手动调用System.exit(0)。

这是目前对于webview 内存泄露 最好的解决方案。使用此方法 所有因为webview引发的 资源无法释放等问题 全部可以解决。

(2)还有一种方法:

动态添加webview,对传入webview中使用的Context使用弱引用,动态添加webview意思在布局创建个viewGroup用来放置webview,Activity创建时add进来,在Activity停止时remove掉

2.WebView中使用setBuiltInZoomControls进行缩放并destroy webview时崩溃

问题描述:webview使用settings.setBuiltInZoomControls(true);进行控制缩放。由于某些原因需要在该activity的onDestroy方法里面调用webView.destroy()。当进入该webview并且进行缩放操作时,退出该activity程序崩溃。

settings代码如下:

settings = previewWebview.getSettings();
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setBuiltInZoomControls(true);
settings.setDefaultTextEncodingName("gbk");

启用后,用户一旦触摸屏幕,就会出现缩放控制图标。这个图标过上几秒会自动消失,但在3.X系统上,如果图标自动消失前退出当前Activity的话,就会报异常。

最终解决方法:

在Activity的onDestroy里面加上这么一句:web.setVisibility(View.GONE);把WebView设置为GONE就可以了

3.后台无法释放js 导致耗电

这个可能很少有人知道,你如果webview加载的html里 有一些js 一直在执行比如动画之类的东西,如果此刻webview 挂在了后台
这些资源是不会被释放,用户也无法感知,导致一直占有cpu 耗电特别快,所以大家记住了,如果遇到这种情况 请在onstop和onresume里分别把setJavaScriptEnabled();
给设置成false和true

4.Android中如何直接调用JS中的函数?

1.html中有js的方法callJs()里面去调用alert()方法
2.webview.setWebChromeClient()中的onJsAlert()去处理JS对话框
3.webview.loadUrl(“javascript:callJS()”)去直接调用

问:如何通过evaluateJavascript直接调用JS中的函数?

webview.evaluateJavascript(“javascript:callJS()”)去调用JS的方法,并且在ValueCallback中能获取JS的返回值。

建议混合使用上面的两种交互方法

1.API < 18, Android 4.4以下使用loadUrl
2.API >=18, 使用evaluateJavascript

5.JS调用Android有哪些方法?

  1. 通过WebView的addJavascriptInterface()进行对象映射
  2. 通过WebViewClient的shouldOverrideUrlLoading()方法回调拦截url
  3. 通过WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt()消息

问:addJavascriptInterface()对象映射是如何使用的?

  • html中调用某对象的某个方法:如jsObject.hello(“js调用了android中的hello方法”);
  • Android中实现一个自定义类,具有方法hello(),该方法使用注解@JavascriptInterface
  • 进行映射webview.addJavascriptInterface(new 自定义类(), “jsObject”)
  • 加载js代码:webview.loadUrl(“file:///android_asset/jsCallAndroid.html”);

问:addJavascriptInterface()存在严重漏洞

  • Android 4.2(17)版本开始通过@JavascriptInterface规避该漏洞
  • 该漏洞会导致攻击者能执行任意Java对象的方法。

问:WebViewClient 中对url拦截

  • js中约定url协议
  • Android中在 shouldOverrideUrlLoading进行解析拦截

问:JS中如何获得Android方法执行的返回值?

  • 只能采用特殊方法去处理
  • js定义一个方法,如命名为returnResult(result)
  • android中通过mWebView.loadUrl(“javascript:returnResult(” + result + “)”);将方法返回值作为参数传入进去。

问:如何通过WebChromeClient的onJsAlert()\onJsConfirm()\onJsPrompt()方法回调拦截JS对话框alert()\confirm\prompt()消息

  • Android中通过WebChromeClient的onJsAlert()\onJsConfirm()\onJsPrompt()方法回调分别拦截JS对话框。
  • 本质是JS弹出对画框,Android拦截了对话框,解析参数中的url等信息,去做事先约定好的任务。

总结

6.WebView初始化

问题描述:

1.当App首次打开时,默认是并不初始化浏览器内核的;只有当创建WebView实例的时候,才会创建WebView的基础框架。
所以与浏览器不同,App中打开WebView的第一步并不是建立连接,而是启动浏览器内核。

2.在浏览器中,我们输入地址时(甚至在之前),浏览器就可以开始加载页面。而在客户端中,客户端需要先花费时间初始化WebView完成后,才开始加载。

解决方法

方案1,全局WebView

在客户端刚启动时,就初始化一个全局的WebView待用,并隐藏;当用户访问了WebView时,直接使用这个WebView加载对应网页,并展示。这种方法可以比较有效的减少WebView在App中的首次打开时间。当用户访问页面时,不需要初始化WebView的时间。当然这也带来了一些问题,包括:额外的内存消耗。页面间跳转需要清空上一个页面的痕迹,更容易内存泄露。

方法2,客户端代理数据请求
在客户端初始化WebView的同时,直接由native开始网络请求数据;当页面初始化完成后,向native获取其代理请求的数据。此方法虽然不能减小WebView初始化时间,但数据请求和WebView初始化可以并行进行,总体的页面加载时间就缩短了;缩短总体的页面加载时间:
还有其他各种优化的方式,不再一一列举,总结起来都是围绕两点:
在使用前预先初始化好WebView,从而减小耗时。
在初始化的同时,通过Native来完成一些网络请求等过程,使得WebView初始化不是完全的阻塞后续过程。

7.描述一下Webview的作用

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

8.WebView的内核是什么

Android的Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome。

9.描述一下WebView与js的交互方式

https://blog.csdn.net/carson_ho/article/details/64904691

10.描述一下WebView的缓存机制

https://www.jianshu.com/p/5e7075f4875f

11.关于WebView的优化你知道哪些

https://www.jianshu.com/p/95d4d73be3d1

12.有没有用过第三方WebView组件?讲一讲优势

https://www.jianshu.com/p/d3ef9c62b6c8

你可能感兴趣的:(android,学习,面试,android,webview)