android 重定向 参数无6,Android Webview 性能优化

1、内存泄漏解决方法

复写Webview,实现如下方法

public MyWebView(Context context, AttributeSet attrs) {

super(context, attrs, android.R.attr.webViewStyle);

setBackgroundColor(Color.TRANSPARENT);

// 删除掉Android默认注册的JS接口

removeDefaultJavascriptInterface();

WindowManager wm= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);

setConfigCallback(wm);

}

@Override

public void destroy() {

getSettings().setJavaScriptEnabled(false);

this.clearFormData();

this.clearHistory();

this.destoryWebView();

super.destroy();

}

private void destoryWebView() {

this.stopLoading();

this.removeAllViews();

if(this.getParent()!=null){

//处理webview无法释放造成的内存泄漏,必须在destroy之前调用

ViewGroup parent = (ViewGroup) this.getParent();

parent.removeView(this);

setConfigCallback(null);

}

}

public void setConfigCallback(WindowManager windowManager) {

try {

if(Build.VERSION.SDK_INT>15) {

return;

}

Field field = WebView.class.getDeclaredField("mWebViewCore");

field = field.getType().getDeclaredField("mBrowserFrame");

field = field.getType().getDeclaredField("sConfigCallback");

field.setAccessible(true);

Object configCallback = field.get(null);

if (null == configCallback) {

return;

}

field = field.getType().getDeclaredField("mWindowManager");

field.setAccessible(true);

field.set(configCallback, windowManager);

} catch(Exception e) {

e.printStackTrace();

return;

}

}

参考:

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

https://blog.youkuaiyun.com/xygy8860/article/details/53334476?utm_source=itdadao&utm_medium=referral

https://stackoverflow.com/questions/11995270/error-webview-destroy-called-while-still-attached/12408703#12408703

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

org.chromium.android_webview.AwContents源码https://github.com/pwnall/chromeview/blob/master/src/org/chromium/android_webview/AwContents.java

https://chromium.googlesource.com/chromium/src/android_webview/glue/+/master/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java

2、SSL证书处理

https://blog.youkuaiyun.com/zoeice/article/details/13996579

3、常见问题处理

4.onPageFinished被调用多次

使用onPageProgressChanged代替

private void handleProgress(WebView view, int newProgress){

if(progressPending.get()!=newProgress){

progressPending.set(newProgress);

onProgressChanged(newProgress);

}

}

@Override

public final void onProgressChanged(WebView view, int newProgress) {

super.onProgressChanged(view, newProgress);

handleProgress(view,newProgress);

}

public void onProgressChanged(int newProgress){

Log.i("WebChromeClient","progress="+newProgress+"%");

if(newProgress==100){

Log.i("WebChromeClient","加载完成");

}

}

5.WebChromeClient接口中onReceiveTitle返回的标题是url

解决方法如下

@Override

public final void onReceivedTitle(WebView view, String title) {

super.onReceivedTitle(view, title);

handleProgress(view,view.getProgress());

if(URLUtils.isNetworkUrl(title)){

return;

}

if(!TextUtils.isEmpty(title) && !TextUtils.isEmpty(view.getUrl())&& !view.getUrl().contains(title)){

onReceivedTitle(title);

}

}

public void onReceivedTitle( String title){

}

6.使用ApplicationContext

使用ApplicationContext可以减少对当前Activity的依赖,便于内存释放,但是这里还有一些问题需要处理,比如ApplicationContext不能加载主题,必须通过ContextThemeWrapper加载。此外,如果使用了ApplicationContext时没有设置WebChromeClient的情况下,alert,confirm等对话框无法显示。

无法显示的原因可以参考源码:

https://chromium.googlesource.com/chromium/src/android_webview/glue/+/master/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java

private boolean showDefaultJsDialog(JsPromptResult res, int jsDialogType, String defaultValue,

String message, String url) {

如果Context不是一个Activity是不允许显示的

Context activityContext = AwContents.activityFromContext(mContext);

if (activityContext == null) {

Log.w(TAG, "Unable to create JsDialog without an Activity");

return false;

}

try {

new JsDialogHelper(res, jsDialogType, defaultValue, message, url)

.showDialog(activityContext);

} catch (WindowManager.BadTokenException e) {

Log.w(TAG,

"Unable to create JsDialog. Has this WebView outlived the Activity it was created with?");

return false;

}

return true;

}

a4d0f03dcbd13544e4dafd8186457031.png

继承关系图

2a7ff8ff9f8fbc1b0d15b1583a95151f.png

如果h5页面不适用alert,confirm等,可以使用ApplicationContext,否则建议使用activitiy或者设置WebChromeClient自行实现。这里提供一个使用ApplicaitonContext的例子。

public MyWebView(Context context, AttributeSet attrs) {

super(WebThemeContext.wrapper(context), attrs, android.R.attr.webViewStyle);

}

public class WebThemeContext extends ContextThemeWrapper {

public WebThemeContext ( Context context) {

super(MyApplication.getInstance(), context.getTheme()); //设置主题

}

public static WebThemeContext wrapper( Context context){

return new WebThemeContext(context);

}

@Override

public Context getApplicationContext() {

return getInstance.getInstance();

}

}

7.性能监控

https://blog.youkuaiyun.com/lmj623565791/article/details/58626355

8.Android WebView 输入框键盘不弹出

在复写MyView时,使用的主题id必须设置,并且设置为android.R.attr.webViewStyle,否则无法调用native服务,如键盘

9.Android Webview是否应该开启硬件加速

由于碎片化问题太多,建议保持默认状态【默认表示由系统决定,不要手动设置】,否则可能产生问题。

10.Cookie同步导致的内存泄漏

使用CookieSyncManager同步时,会永久引用第一个acitivity的的Context,为了避免此种情况,请使用ApplicationContext

if (Build.VERSION.SDK_INT < 21) {

android.webkit.CookieSyncManager.createInstance(context.getApplicationContext());

}

11. 30x重定向问题

Android Webview重定向可能导致Android 5.0和5.0之前的Webview内核死锁,而且会导致资源无法释放。一旦内核死锁,那么整个app必须重启才能加载网页,否则一直处于空白状态。

12.loadUrl(url,map)方法加载带hash(带#号)的url导致刷新问题或请求头缓存问题。

① 如果调用loadUrl(url,map)方法去加载资源,那么在此调用loadUrl(ur),reload,loadUrl(url,map)造成无法刷新的问题。这个现象主要出现在Android 8.0的系统中。

可尝试调用如下url尝试:

https://baike.baidu.com/item/%E9%83%8E%E5%B9%B3/58857#/

https://baike.baidu.com/item/%E9%83%8E%E5%B9%B3/58857#/?a=123

https://baike.baidu.com/item/%E9%83%8E%E5%B9%B3/58857#3

②loadUrl(url,map) 第二个参数map中传入的数据用于请求头,此外这个请求头数据会被webview缓存下来,刷新时,请求头中的数据还是原来的,因此,不适用传入需要进程变化的“状态”信息。

解决方法:不要使用loadUrl(url,map),推荐使用loadUrl(url),如果非要传输参数,还不如在url中添加参数。

13.Android 4.2.2 系统注入javascript脚本导致页面循环刷新,导致内核闪退。

Android 4.2.2进行了一次内核调整,但是遗留了一部分bug,就是在js脚本注入的时候,必须得添加 “javascript:”前缀,否则页面将无限刷新,最后ANR。因此,这里建议任何脚本,必须添加 "javscript:"前缀。

14.copyBackForwardList调用时引起空指针问题

部分手机上调用copyBackForwardList会出现空指针问题,需要处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值