Java Question Admob Interstitial Library Memory Leak

Discussion in 'Libraries developers questions' started by Jack Cole, Mar 13, 2015.

  1. Jack Cole

    Jack Cole Active Member Licensed 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:

    Here is my code for the wrapper.

    Code:
    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;
      }
    }
     
    MarcoRome likes this.
  2. DonManfred

    DonManfred Expert Licensed User

    i would use
    Code:
    this.interstitialAds = new InterstitialAd(ba.context);
     
  3. Jack Cole

    Jack Cole Active Member Licensed User

    That seemed to help some, but it's still losing about 500KB each time orientation is changed. Maybe that's the best that can be hoped for.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice