Webview内存泄漏与内存占用过大OOM的优化
1.首先不能直接在xml写webview组件,用FrameLayout做容器,java中动态添加:<FrameLayoutandroid:id="@+id/content"android:layout_width="match_parent"android:layout_height="wrap_
·
1.首先不能直接在xml写webview组件,用FrameLayout做容器,java中动态添加:
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/video_desc_margin_top"></FrameLayout>
2.
FrameLayout ll = (FrameLayout) findViewById(R.id.content);
// wvContent = new WebView(getApplicationContext());
wvContent = new WebView(weakReference.get());
ll.addView(wvContent);
3.销毁时要先销毁外部的容器
:
4.再不行:
5.或者:通过反射清楚webview的内存占用
在Activity中回调:
@Override
protected void onDestroy() {
// Destroy the AdView.
if (wvContent != null) {
wvContent.removeAllViews();
ll.removeView(wvContent);
wvContent.destroy();
}
super.onDestroy();
}
4.再不行:
package com.mycompany.view;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.AttributeSet;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class NonLeakingWebView extends WebView {
private static Field sConfigCallback;
static {
try {
sConfigCallback = Class.forName("android.webkit.BrowserFrame").getDeclaredField("sConfigCallback");
sConfigCallback.setAccessible(true);
} catch (Exception e) {
// ignored
}
}
public NonLeakingWebView(Context context) {
super(context.getApplicationContext());
setWebViewClient( new MyWebViewClient((Activity)context) );
}
public NonLeakingWebView(Context context, AttributeSet attrs) {
super(context.getApplicationContext(), attrs);
setWebViewClient(new MyWebViewClient((Activity)context));
}
public NonLeakingWebView(Context context, AttributeSet attrs, int defStyle) {
super(context.getApplicationContext(), attrs, defStyle);
setWebViewClient(new MyWebViewClient((Activity)context));
}
@Override
public void destroy() {
super.destroy();
try {
if( sConfigCallback!=null )
sConfigCallback.set(null, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected static class MyWebViewClient extends WebViewClient {
protected WeakReference<Activity> activityRef;
public MyWebViewClient( Activity activity ) {
this.activityRef = new WeakReference<Activity>(activity);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
try {
final Activity activity = activityRef.get();
if( activity!=null )
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}catch( RuntimeException ignored ) {
// ignore any url parsing exceptions
}
return true;
}
}
}
5.或者:通过反射清楚webview的内存占用
public void setConfigCallback(WindowManager windowManager) {
try {
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) {
}
}
在Activity中回调:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setConfigCallback((WindowManager)getApplicationContext().getSystemService(Context.WINDOW_SERVICE));
}
public void onDestroy() {
setConfigCallback(null);
super.onDestroy();
}
更多推荐
已为社区贡献1条内容
所有评论(0)