1.webView常见的一些坑
- 1.Android API level 16以及之前的版本存在远程代码执行安全漏洞,该漏洞源于程序没有正确限制使用webView.addJavascriptInterface方法,远程攻击者可通过使用Java Refection API利用该漏洞执行任意Java对象的方法。
- 2.webView在布局文件中的使用:webView写在其他容器中时,必须先将webview从该容器中remove掉,在调用webview的removeAllViews 和webview的destory方法,才能真正的销毁整个webview,否则会出现内存泄漏问题。
- 3.jsbridge :就是android端与web端之间的桥梁。实现两个端互调。
- 4.webViewClient.onPageFinished:他会判断这个网页内容是否真的已经加载完毕。而如果当前网页产生跳转的话这个方法会被加载无数次。所以我们一般使用webChromeClient.onProgressChanged。
- 5.后台耗电 当webview加载网页时 ,webView会自己开启线程,如果webview没有很好的被销毁的话,这个线程会一直在运行,导致耗电量居高不下。
- 6.webView硬件加速导致页面渲染问题 暂时没有更好的解决方法。只能关闭硬件加速。
- 7.webview嵌套h5支付。比如支付宝支付 微信支付的时候 需要使用webview.loadUrl(url,map)方法。map里put一个Referer,这个Referer由H5的同事提供。另外自定义WebViewClient,重写shouldOverrideUrlLoading()方法 具体代码如下(请根据自己的业务需求修改):
private class MyWebViewClient extends WebViewClient {
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.e("hjj", url);
if (url.endsWith(".apk")) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse(url.trim());
try {
browserIntent.setData(uri);
startActivity(browserIntent);
} catch (Exception e) {
PackageManager packageManager = getPackageManager();
browserIntent.setDataAndType(uri, "text/html");
List<ResolveInfo> list = packageManager.queryIntentActivities(browserIntent, 0);
for (ResolveInfo resolveInfo : list) {
String activityName = resolveInfo.activityInfo.name;
if (activityName.contains("BrowserActivity")) {
browserIntent =
packageManager.getLaunchIntentForPackage(resolveInfo.activityInfo.packageName);
ComponentName comp =
new ComponentName(resolveInfo.activityInfo.packageName, resolveInfo.activityInfo.name);
browserIntent.setAction(Intent.ACTION_VIEW);
browserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
browserIntent.setComponent(comp);
browserIntent.setData(uri);
}
}
startActivity(browserIntent);
}
} else {
if (url.startsWith("http") || url.startsWith("https")) {
view.loadUrl(url, headers);
} else {
try {
startActivity(new Intent("android.intent.action.VIEW", Uri.parse(url)));
} catch (Exception e) {
if (url.startsWith("alipays://") && !PlatformUtil.isInstallApp(GameActivity.this, PlatformUtil.PACKAGE_ALIPAY)) {
new AlertDialog.Builder(GameActivity.this)
.setMessage("未检测到支付宝客户端,请安装后重试。")
.setPositiveButton(
"立即安装",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Uri alipayUrl = Uri.parse("https://d.alipay.com");
startActivity(new Intent("android.intent.action.VIEW", alipayUrl));
}
}).setNegativeButton("取消", null)
.show();
}
}
return true;
}
}
return false;
}
}
2.避免webview内存泄漏方法
- 1.独立进程,简单暴力,不过可能涉及到进程间通信。
WebView独立进程的实现比较简单,只需要在AndroidManifest中找到对应的WebViewActivity,对其配置"android: process"属性即可。
- 2.动态添加webView,对传入webView中使用的Context使用弱引用,动态添加WebView意思在布局创建个viewGroup用来放置WebView,Activity创建时add进来。在activity停止时remove掉。在调用webview的removeAllViews 和webview的destory方法。