WebView泄漏内存

时间:2014-08-12 16:22:08

标签: android memory-leaks webview

我们在设备上安装了一个WebView,它包含了一些包含javascript的10页。 问题是泄漏,我不知道它会从哪里来。 基本上有一个Activity有ViewPager,ViewPager有.setAdapter “new WebPagerAdapter()”。 WebPagerAdapter扩展了PagerAdapter。

问题是这是在某处泄漏,我们尝试的一切都无法正常工作。看起来在一台设备上它会不断地在RAM占用率上升到5-10mb左右,但它一直在增加,而且在一天之后就会使用150MB。 堆转储没有显示任何有用的东西,“dumpsys meminfo”在对象下显示越来越多的“视图”? 我不知道该怎么办,有什么建议吗?

这是WebPagerAdapter上的instatiateItem

@Override
public Object instantiateItem(ViewGroup container, int position) {
    NonLeakingWebView mwebView = new NonLeakingWebView(activity.getApplicationContext());
    if (mWebViewClientLogScreen == null)
        mWebViewClientLogScreen = new WebViewClientLogScreen(activity);
    mwebView.setWebViewClient(mWebViewClientLogScreen);
    mwebView.clearCache(true);
    mwebView.setWebChromeClient(new WebChromeClient());

    if (pos >= lenght)
        pos = 0;


    mwebView.getSettings().setJavaScriptEnabled(true);
    mwebView.setTag(String.valueOf(pos));
    mwebView.loadUrl(imageArray[pos]);
    ++pos;
    // view.addView(mwebView);
    container.addView(mwebView, 0);

    return mwebView;
}

NonLeakingWebView是来自https://stackoverflow.com/a/8949378/1088975

的WebView

销毁物品

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    try {
        NonLeakingWebView mWebView = (NonLeakingWebView) object;
        container.removeView(mWebView);
        mWebView.removeAllViews();
        mWebView.clearHistory();
        mWebView.clearView();
        mWebView.clearCache(true);
        mWebView.freeMemory();
        mWebView.destroy();
        Class.forName("android.webkit.WebView").getMethod("onPause", (Class[]) null).invoke(mWebView, (Object[]) null);
        mWebView = null;
        System.gc();
    } catch (Exception e) {
        e.printStackTrace();
    }
    container.removeView((View) object);
}

有.onPause()因为我们试图暂停以查看是否存在差异

public class NLAwebPager extends ViewPager {

public NLAwebPager(Context context) {
    super(context);
}

public NLAwebPager(Context context, AttributeSet attr) {
    super(context, attr);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
    return true;
}

}

这是自定义ViewPager,它在主要活动中执行此操作

    NLPager= (NLAwebPager) findViewById(R.id.frame);
    NLPager.setOnPageChangeListener(new OnPageChangeListener() {

        @Override
        public void onPageSelected(int arg0) {
            WebView mWebVIew = (WebView) NLPager.findViewWithTag(--arg0);
            if (mWebVIew != null)
                mWebVIew.onPause();
        }

        @Override
        public void onPageScrolled(int arg0, float arg1, int arg2) {
            // Log.e("ss", "s");
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {

        }
    });

这是一个Runnable,每隔X秒就会更改适配器页面

private Runnable runnable_webPage = new Runnable() {

    @Override
    public void run() {
        i = txtTime.getCurrentItem();
        txtTime.setCurrentItem(++i, false);

        mHandlerWebPage.removeCallbacks(runnable_webPage);
        mHandlerWebPage.postDelayed(runnable_webPage, webPageChangeTimer);
    }

};

用于进度条的自定义WebViewClient

public class WebViewClientLogScreen extends WebViewClient {

LogScreen wpa;

public WebViewClientLogScreen(FragmentActivity wpa) {
    this.wpa = (LogScreen) wpa;
}

@Override
public void onPageFinished(WebView view, String url) {
    super.onPageFinished(view, url);
    try {
        ProgressBar mbar = (ProgressBar) view.getTag();
        mbar.setVisibility(View.GONE);
    } catch (Exception e) {
    }
}

@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
    super.onPageStarted(view, url, favicon);
    try {
        ProgressBar mbar = (ProgressBar) view.getTag();
        mbar.setVisibility(View.VISIBLE);
    } catch (Exception e) {
    }
}

@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    super.onReceivedError(view, errorCode, description, failingUrl);
    try {
        wpa.doShowMessage();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    return false;
}

}

0 个答案:

没有答案