Java Question Admob Interstitial Library Memory Leak

Jack Cole

Well-Known Member
Licensed User
Longtime User
My wrapper for Admob interstitials has a memory leak. This occurs when you change orientations or load a new activity (that loads an interstitial) and close the activity. Part of the notion is that the library is holding a pointer to the activity, which prevents the activity and interstitial from being garbage collected. Any ideas for fixing this would be appreciated.

There is a post of stackoverflow.com that suggests the following:

interstitial =newInterstitialAd(this);

to

interstitial =newInterstitialAd(getApplicationContext());

Here is my code for the wrapper.

B4X:
package mobi.mindware.admob.interstitial;

import android.app.Activity;
import android.util.Log;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.BA.ActivityObject;
import anywheresoftware.b4a.BA.Author;
import anywheresoftware.b4a.BA.DependsOn;
import anywheresoftware.b4a.BA.Events;
import anywheresoftware.b4a.BA.Permissions;
import anywheresoftware.b4a.BA.ShortName;
import anywheresoftware.b4a.BA.Version;
import com.google.android.gms.ads.*;
import android.os.Bundle;
import com.google.android.gms.ads.AdListener;

@BA.ActivityObject
@BA.ShortName("mwAdmobInterstitial")
@BA.Version(2.0F)
@BA.Author("Jack Cole")
@DependsOn(values={"google-play-services"})
@Permissions(values={"android.permission.INTERNET", "android.permission.ACCESS_NETWORK_STATE","android.permission.ACCESS_WIFI_STATE", "android.permission.READ_PHONE_STATE"})
@Events(values={"AdDismissed","AdFailedToLoad (ErrorMessage as String)","AdLoaded","AdClosed","Destroy"})
public class AdmobInterstitialsAds extends Activity
{
  public BA bA;
  private String eventName;
  private InterstitialAd interstitialAds;
  public Boolean isAdLoaded;
  public int Status;
  public static final int Status_Initialized = 0;
  public static final int Status_LoadingAd = 1;
  public static final int Status_AdReadyToShow = 2;
  public static final int Status_ShowingAd = 3;
  public static final int Status_NoAdAvailable = 4;
  public static final int Status_Dismissed = 5;
  public boolean isInitialized = false;

  public void Initialize(BA ba, String EventName, String AppId)
  {
      //Log.i("B4A", "1 - start initialize");
      this.isAdLoaded = Boolean.valueOf(false);

    this.bA = ba;

    this.eventName = EventName.toLowerCase(BA.cul);
    //
    this.interstitialAds = new InterstitialAd(ba.applicationContext);
    //this.interstitialAds = new InterstitialAd(Context.getApplicationContext());
    this.interstitialAds.setAdUnitId(AppId);
    //Log.i("B4A", "1 - before ad listener defined");
    this.interstitialAds.setAdListener(new AdListener() {
        @Override
        public void onAdLoaded() {
            //Log.i("B4A", "ON ad RECEIVED ");
            Status = 2;
            isAdLoaded = Boolean.valueOf(true);
            if (bA.subExists(eventName + "_adloaded"))
              bA.raiseEvent(this, eventName + "_adloaded", new Object[0]);
        }

        @Override
        public void onAdFailedToLoad(int errorCode) {
            Status = 4;
            //Log.i("B4A", "ON FAILED TO RECEIVE " + errorCode);
           
            if (bA.subExists(eventName + "_adfailedtoload"))
              bA.raiseEvent(this, eventName + "_adfailedtoload", new Object[] { getErrorReason(errorCode) });
        }

        @Override
        public void onAdClosed() {
            Status = 5;
           
            if (bA.subExists(eventName + "_adclosed"))
                bA.raiseEventFromDifferentThread(this, null, 0, eventName + "_adclosed", false, null);
        }
        @Override
        public void onAdLeftApplication() {
           
        } 
      

    });

    //Log.i("B4A", "1 - initialize end");
    this.isInitialized = true;
    this.Status = 0;
  }
 

  public void Destroy(BA ba){
      this.interstitialAds.setAdListener(null);
      this.interstitialAds=null;
  }
 
 
  public void LoadAd(BA ba) {
    this.interstitialAds.loadAd(new AdRequest.Builder().build());
    this.Status = 1;
  }

  public void Show(BA ba) {
    if (this.interstitialAds.isLoaded()) {
      this.interstitialAds.show();
      this.Status = 3;
    }
  }

  /** Gets a string error reason from an error code. */
  private String getErrorReason(int errorCode) {
    String errorReason = "";
    switch(errorCode) {
      case AdRequest.ERROR_CODE_INTERNAL_ERROR:
        errorReason = "Internal error";
        break;
      case AdRequest.ERROR_CODE_INVALID_REQUEST:
        errorReason = "Invalid request";
        break;
      case AdRequest.ERROR_CODE_NETWORK_ERROR:
        errorReason = "Network Error";
        break;
      case AdRequest.ERROR_CODE_NO_FILL:
        errorReason = "No fill";
        break;
    }
    return errorReason;
  }
}
 

DonManfred

Expert
Licensed User
Longtime User
this.interstitialAds = new InterstitialAd(ba.applicationContext);
i would use
B4X:
this.interstitialAds = new InterstitialAd(ba.context);
 
Top