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.
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;
}
}