I'm trying to implement AdMob in my application as an exercise. I followed the tutorial to the letter (read: copy/pasted code from the sample into my app). I ended up with an activity, where onCreate() had the following code:
// Look up the AdView as a resource and load a request.
AdView adView = (AdView)this.findViewById(R.id.adView);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
and a layout like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:ads="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/windowBackgroundColor"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".SettingsActivity"
android:id="@+id/mainLayout">
<com.google.android.gms.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@color/navigationBarColor"
ads:adSize="BANNER"
ads:adUnitId="@string/banner_ad_unit_id">
</com.google.android.gms.ads.AdView>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_above="@+id/adView">
<!-- ... -->
</RelativeLayout>
</RelativeLayout>
Pretty simple. However, I found that after rotating the screen several times, I would end up with a bunch of Activity instances hung by some ad threads. Not nice.
My salvation came from this StackOverflow answer. Apparently, null-ifying the references by hand and removing the ad view from the layout allows the activity to finish. The destroyAdView() below has the gist:
private void destroyAdView() {
if (adView != null) {
adRequest = null;
adView.removeAllViews();
adView.setAdListener(null);
adView.destroy();
snippetContent.removeView(adView);
adView = null;
snippetContent = null;
}
}
Note: One thing to note is if you test on a physical device and rotate the screen, even after a GC trigger you may still have several references up and running. You're OK as long as you have Finalizer classes. This means that whatever the ad process is doing hasn't finished yet. If you wait a bit more, the finalizer queue empties and the ad instances go away.
Some links to feed your apetite:
- Stack overflow - adview leaking
- RaziLabs - bug hunting
- Eclipse - The memory analyzer
- Android - avoiding memory leaks (a bit less relevant to the problem because you don't control the leaker code)
- Hprof-conv because you need to convert the androidf hprof dump to something the memory analyzer can process
- Another good memory leak article and its SO source
HTH,
Member discussion: