技术标签: hybrid android Android相关
因为关于WebView的相关细节还有很多,我就不一一写例子说明,一口气全写出来凭注释说明了
用于配置WebVIew的类
WebSettings webSettings = mWebView.getSettings();
if (webSettings == null) return;
//设置字体缩放倍数,默认100
webSettings.setTextZoom(100);
// 支持 Js 使用
webSettings.setJavaScriptEnabled(true);
// 开启DOM缓存
webSettings.setDomStorageEnabled(true);
// 开启数据库缓存
webSettings.setDatabaseEnabled(true);
// 支持自动加载图片
webSettings.setLoadsImagesAutomatically(hasKitkat());
// 设置 WebView 的缓存模式
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
// 支持启用缓存模式
webSettings.setAppCacheEnabled(true);
// 设置 AppCache 最大缓存值(现在官方已经不提倡使用,已废弃)
webSettings.setAppCacheMaxSize(8 * 1024 * 1024);
// Android 私有缓存存储,如果你不调用setAppCachePath方法,WebView将不会产生这个目录
webSettings.setAppCachePath(getCacheDir().getAbsolutePath());
// 数据库路径
if (!hasKitkat()) {
webSettings.setDatabasePath(getDatabasePath("html").getPath());
}
// 关闭密码保存提醒功能
webSettings.setSavePassword(false);
// 支持缩放
webSettings.setSupportZoom(true);
// 设置 UserAgent 属性
webSettings.setUserAgentString("");
// 允许加载本地 html 文件/false
webSettings.setAllowFileAccess(true);
// 允许通过 file url 加载的 Javascript 读取其他的本地文件,Android 4.1 之前默认是true,在 Android 4.1 及以后默认是false,也就是禁止
webSettings.setAllowFileAccessFromFileURLs(false);
// 允许通过 file url 加载的 Javascript 可以访问其他的源,包括其他的文件和 http,https 等其他的源,
// Android 4.1 之前默认是true,在 Android 4.1 及以后默认是false,也就是禁止
// 如果此设置是允许,则 setAllowFileAccessFromFileURLs 不起做用
webSettings.setAllowUniversalAccessFromFileURLs(false);
/**
* 关于缓存目录:
*
* 我自测发现以下规律,如果你有涉及到目录操作,需要自己做下验证。
* Android 4.4 以下:/data/data/包名/cache
* Android 4.4 - 5.0:/data/data/包名/app_webview/cache/
*/
因为Android4.4开始可以使用Chrome作为WebView的内核,所以关于这个WebViewClient,还有一个WebChromeClient
private void initListener() {
mWebView.setWebViewClient(new SafeWebViewClient());
mWebView.setWebChromeClient(new SafeWebChromeClient());
}
public class SafeWebViewClient extends WebViewClient {
/**
* 当WebView得页面Scale值发生改变时回调
*/
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
super.onScaleChanged(view, oldScale, newScale);
}
/**
* 是否在 WebView 内加载页面
*
* @param view
* @param url
* @return
*/
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
/**
* WebView 开始加载页面时回调,一次Frame加载对应一次回调
*
* @param view
* @param url
* @param favicon
*/
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
/**
* WebView 完成加载页面时回调,一次Frame加载对应一次回调
*
* @param view
* @param url
*/
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
/**
* WebView 加载页面资源时会回调,每一个资源产生的一次网络加载,除非本地有当前 url 对应有缓存,否则就会加载。
*
* @param view WebView
* @param url url
*/
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
}
/**
* WebView 可以拦截某一次的 request 来返回我们自己加载的数据,这个方法在后面缓存会有很大作用。
*
* @param view WebView
* @param request 当前产生 request 请求
* @return WebResourceResponse
*/
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return super.shouldInterceptRequest(view, request);
}
/**
* WebView 访问 url 出错
*
* @param view
* @param request
* @param error
*/
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
}
/**
* WebView ssl 访问证书出错,handler.cancel()取消加载,handler.proceed()对然错误也继续加载
*
* @param view
* @param handler
* @param error
*/
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
}
}
public class SafeWebChromeClient extends WebChromeClient {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
return super.onConsoleMessage(consoleMessage);
}
/**
* 当前 WebView 加载网页进度
*
* @param view
* @param newProgress
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
/**
* Js 中调用 alert() 函数,产生的对话框
*
* @param view
* @param url
* @param message
* @param result
* @return
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
/**
* 处理 Js 中的 Confirm 对话框
*
* @param view
* @param url
* @param message
* @param result
* @return
*/
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return super.onJsConfirm(view, url, message, result);
}
/**
* 处理 JS 中的 Prompt对话框
*
* @param view
* @param url
* @param message
* @param defaultValue
* @param result
* @return
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
return super.onJsPrompt(view, url, message, defaultValue, result);
}
/**
* 接收web页面的icon
*
* @param view
* @param icon
*/
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
}
/**
* 接收web页面的 Title
*
* @param view
* @param title
*/
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
}
关于JS注入存在的安全问题,通过以下自定义WebView的代码能够填坑
public class SafeWebView extends WebView {
public SafeWebView(Context context) {
super(context);
removeSearchBox();
}
public SafeWebView(Context context, AttributeSet attrs) {
super(context, attrs);
removeSearchBox();
}
public SafeWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
removeSearchBox();
}
/**
* 移除系统注入的对象,避免js漏洞
* <p>
* https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-1939
* https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-7224
*/
private void removeSearchBox() {
super.removeJavascriptInterface("searchBoxJavaBridge_");
super.removeJavascriptInterface("accessibility");
super.removeJavascriptInterface("accessibilityTraversal");
}
public static void disableAccessibility(Context context) {
if (Build.VERSION.SDK_INT == 17/*4.2 (Build.VERSION_CODES.JELLY_BEAN_MR1)*/) {
if (context != null) {
try {
AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (!am.isEnabled()) {
//Not need to disable accessibility
return;
}
Method setState = am.getClass().getDeclaredMethod("setState", int.class);
setState.setAccessible(true);
setState.invoke(am, 0);/**{@link AccessibilityManager#STATE_FLAG_ACCESSIBILITY_ENABLED}*/
} catch (Exception ignored) {
ignored.printStackTrace();
}
}
}
}
@Override
public void setOverScrollMode(int mode) {
// try {
// super.setOverScrollMode(mode);
// } catch (Throwable e) {
// e.printStackTrace();
// }
try {
super.setOverScrollMode(mode);
} catch (Throwable e) {
String trace = Log.getStackTraceString(e);
if (trace.contains("android.content.pm.PackageManager$NameNotFoundException")
|| trace.contains("java.lang.RuntimeException: Cannot load WebView")
|| trace.contains("android.webkit.WebViewFactory$MissingWebViewPackageException: Failed to load WebView provider: No WebView installed")) {
e.printStackTrace();
} else {
throw e;
}
}
}
@Override
public boolean isPrivateBrowsingEnabled() {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 && getSettings() == null) {
return false;
} else {
return super.isPrivateBrowsingEnabled();
}
}
}
参考文章
文章浏览阅读384次。数据结构实验之栈与队列四:括号匹配Time Limit:1000 msMemory Limit:65536 KiBSubmitStatisticProblem Description给你一串字符,不超过50个字符,可能包括括号、数字、字母、标点符号、空格,你的任务是检查这一串字符中的( ) ,[ ],{ }是否匹配。Input输入数据有多组,处理到文件结束。..._数据结构_习题三_栈和队列04:括号匹配 c++描述 给定一个字符串,字符串只包含两种
文章浏览阅读1.1k次。编辑丨极市平台NTIRE英文全称是New Trends in Image Restoration and Enhancement,也就是“图像恢复与增强的新趋势”,是近年来计算机图像恢复领..._new trends in image restoration and enhancement
文章浏览阅读1.7k次,点赞7次,收藏21次。前言原生JS篇JS是一种什么样的语言?解释性脚本语言,代码不进行预编译主要用来向HTML页面添加交互行为可以直接嵌入HTML页面,但单独写成JS文件有利于结构和行为的分离跨平台性,在绝大多数浏览器的支持下,可以在多种平台下运行:linux、windowsJS数据类型有哪些?栈: (原始数据) string/number/boolean/null/undefined/symbol堆: (引用数据类型)object(array和函数属于object)数据类型一共7(6种基本类型+1种引用_创建一个空对象 data,并使用 validator 对象创建了一个代理 proxy。 当我们通过代
文章浏览阅读308次,点赞4次,收藏5次。因为DexClassLoader 参数需要一个文件路径 但是assets 中的文件并不是一个普通的文件路径,而是一个封装在 APK 中的资源。因此,你必须先将 dex 文件从 assets 复制到设备上的一个可访问的目录,然后再使用 DexClassLoader 加载它。新建了两个脚本 loadTest NetTool。将dex文件复制到另一个工程的assets目录下。jadx查看dex文件的结构。_d:\app\myapplication11\app\build\intermediates\project_dex_archive\debug\out
文章浏览阅读846次。项目需要用到高并发,选用swoole模式的hyperf框架,由于win下不支持协程,故在docker中运行。_docker开发hyperf
文章浏览阅读277次。国内有很多ubuntu的源,包括:网易源(这个之前用过,速度很快的),阿里源,还有很多教育网的源,如:清华源,中科大源。这里要下载的是中科大ubuntu16.04的源列表,可以在这里获得:https://lug.ustc.edu.cn/repogen/编辑/etc/apt/sources.list文件, 在文件最前面添加以下条目(操作前请做好相应备份):打开终端,然后输sudo gedit /et..._20 apt ustc
文章浏览阅读666次。今天咱们来看看老潘微博里的一个python小案例,求100到99999之间的所有水仙花数。所谓水仙花数,又被称为超完全数字不变数、自恋数、自幂数、阿姆斯壮数、阿姆斯特朗数。是指一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本身(153=1^3+5^3+3^3)。严格来说,只有3位数的3次幂数才成为水仙花数,水仙花数只是自幂数的一种。一位自幂数:独身数;二位自幂数:无;三位自幂..._python例2:水仙花数是指一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本
文章浏览阅读955次,点赞19次,收藏26次。oracle_fdw是KingbaseES的一个扩展插件,提供了一个外部数据包装器,可以使KingbaseES方便高效的访问oracle数据库。_oracle_fdw
文章浏览阅读540次。如何为代码选择开源许可证,这是一个问题。世界上的开源许可证,大概有上百种。很少有人搞得清楚它们的区别。即使在最流行的六种:GPL、BSD、MIT、Mozilla、Apache和LGPL,如何在这之中做选择,也很复杂。乌克兰程序员 Paul Bagwell,画了一张分析图,说明应该怎么选择。这是我见过的最简单的讲解,只用两分钟,你就能搞清楚这六种许可证之间的最大区别。下面是阮一峰制作_流行的开源license
文章浏览阅读3.4k次,点赞8次,收藏42次。下载CMIP6数据的几种方法_cmip6数据下载
文章浏览阅读470次。1.牛顿法学习笔记:http://blog.csdn.net/itplus/article/details/21896453?source=1
文章浏览阅读331次,点赞5次,收藏3次。new。