Android: how to solve adview CPU consuming

adview can consume CPU when the application is in the background… This is a very common problem. Even if the application in the background or has been stopped, it can consume the CPU continuously.

Other symptom, if you disable ads, the CPU usage is minimal or zero.

This is caused by several reasons including possible adview bug too. Here, you can see how to solve the high CPU usage problem:

The first one is to destroy the adview in onDestroy() and onPause() (don’t forget to recreate it in onResume() and onCreate()):

private void destroyAdView() {
    if (adview != null) {
        adview.destroy();               
    }   
}

@Override
public void onDestroy() {
    destroyAdView();
    super.onDestroy();
}

@Override
public void onPause() {
    destroyAdView();
    super.onDestroy();
}

In newer admob sdk you can call adview.onPause() and adview.onResume() functions, but my experience that sometimes they don’t do what they promise.

If adview still consumes CPU, there is a second solution: removing the full adview from the layout, not only destroying it:

private void destroyAdView() {
    if (adview != null) {
        // In my case the adview has been added to a relativelayout
        RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.adRelativeLayout);
        layout.removeView(adview);
        adview.destroy();               
    }   
    }

The two solutions above should solve the high CPU usage problem. Excepting only one case:
If you are using the new Google Play services library for adview. Google will only support this admob library after august, 2014.
It seems there is a bug in the library:
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/1aidjtsin8A
https://groups.google.com/forum/#!topic/google-admob-ads-sdk/Qu4G19NFAuI

So if you experience high CPU usage after switching to the new library, you can use a workaround (pausing webview can have other effects too, so use it for your own risk):

@Override
    public void onDestroy() {
        destroyAdView();
        super.onDestroy();
    }
private void destroyAdView() {
    if (adview != null) {
        // In my case the adview has been added to a relativelayout
        RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.adRelativeLayout);
        layout.removeView(adview);
        pauseWebView(adview);
        adview.destroy();               
    }   
    }

private void pauseWebView(ViewGroup v) {
    for (int i = 0; i < v.getChildCount(); i++) {
        View child = v.getChildAt(i);
        if (child instanceof WebView) {
            ((WebView) child).pauseTimers();
        }   
        pauseWebView((ViewGroup) child);
    }   
}

And finally, here is how I am creating the adview and a full example:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
createAdView();
...
}
private void createAdView() {
    if (adview == null) {
        RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.adRelativeLayout);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);

        layout.setLayoutParams(lp);
        RelativeLayout.LayoutParams adsParams = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        adsParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        adsParams.addRule(RelativeLayout.CENTER_IN_PARENT);

        adview = new AdView(fragmentActivity);
        adview.setAdSize(AdSize.BANNER);
        adview.setAdUnitId("ca-xxxx");
        final AdListener listener = new AdListener() {
            @Override
            public void onAdLoaded() {
                //Here we will display the adview if there is ad
                adview.setVisibility(View.VISIBLE);
                super.onAdLoaded();
            }
        };

        adview.setAdListener(listener);

        //This needs to remove empty space when ad is not loaded, for example no internet conn.
        adview.setVisibility(View.GONE);

        layout.addView(adview, adsParams);

        AdRequest adRequest = new AdRequest.Builder().addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
        .build();
        adview.loadAd(adRequest);
    }   
}

void resumeWebView(ViewGroup v) {
        for (int i = 0; i < v.getChildCount(); i++) {
            View child = v.getChildAt(i);
            if (child instanceof WebView) {
                ((WebView) child).resumeTimers();
            }
            try {                
                resumeWebView((ViewGroup) child);
            } catch (Exception e) {
                e.printStackTrace();
            }            
        }
    }

void pauseWebView(ViewGroup v) {     
        for (int i = 0; i < v.getChildCount(); i++) {
            View child = v.getChildAt(i);
            if (child instanceof WebView) {
                ((WebView) child).pauseTimers();
            }
            try {                
                pauseWebView((ViewGroup) child);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

private void destroyAdView() {
        if (adview != null) {
            RelativeLayout layout = (RelativeLayout) mainView.findViewById(R.id.relativeLayout);
            layout.removeView(adview);            
            adview.destroy();            
            adview = null;
        }

    }

 @Override
    public void onPause() {
        if (adview != null) {
            adview.pause();
            pauseWebView(adview);
        }
        super.onPause();
    }

    @Override
    public void onResume() {        
        if (adview != null) {
            adview.resume();
            resumeWebView(adview);
        }
        super.onResume();
    }

@Override
    public void onDestroy() {     
        destroyAdView();
        super.onDestroy();
    }

Advertisements

Comments are closed.

%d bloggers like this: