Android Admob 4.1.1 has a memory leak (see attached test project). Cause/fix/work around?

筅森魡賤 提交于 2019-12-04 14:38:14

My app uses 80% of the allowed 16Mb and the AdView leaks at every orientation change (since android destroys and recreates the whole activity then). As a result I am out of memory after a dozen or so orientation changes giving me the dreaded:

10-08 10:14:47.178: ERROR/dalvikvm-heap(2876): 1440000-byte external allocation too large for this process.

10-08 10:14:47.178: ERROR/dalvikvm(2876): Out of memory: Heap Size=5191KB, Allocated=2877KB, Bitmap Size=18675KB

10-08 10:14:47.178: ERROR/GraphicsJNI(2876): VM won't let us allocate 1440000 bytes

or similar.

The increase in memory can easily be seen in eclipse by doing a debug run and opening Window > Open perspective > Other > DDMS, clicking the "update heap" icon and doing a Cause GC. The easiest way to check imho is the #Objects. If the orientation has changed from portrait to landscape and back, the number of Objects should be exactly the same (and without AdView it is).

I work around the memory leak by making the AdView static

private static AdView mAdView = null;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(mAdView == null)
    {
        mAdView = new AdView(this, AdSize.BANNER, ADMOB_PUBLISHER_ID);
    }
}

and not calling the destroy

@Override
public void onDestroy() {
    super.onDestroy();
    //mAdView.destroyDrawingCache();
    //mAdView.destroy();
    //mAdView = null;
}

At least this prevents memory leaks between every orientation change.

Also I set request to null after using it. Don't know if that helps.

    AdRequest request = new AdRequest();
    mAdView.loadAd(request);
    request = null;

My solution

private void destroyWebView(ViewGroup viewGroup) {
for (int i = 0; i < viewGroup.getChildCount(); i++) {
    if (viewGroup.getChildAt(i) instanceof WebView) {
        WebView view = (WebView) viewGroup.getChildAt(i);
        viewGroup.removeView(view);
        view.destroy();
        return;
    }
}
}

@Override
protected void onDestroy() {
mAdView.stopLoading();
destroyWebView(mAdView);
((ViewGroup) mAdView.getParent()).removeView(mAdView);
Ghandi

Yes, I build it all up dynamically. I use removeAllViews to remove all views from my (LinearLayout) container. Then I use addView to put them all back again. The ad is clickable. Is there perhaps some transparent view in front of it in your case?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!