Android AdMob has memory leak

大城市里の小女人 提交于 2021-01-24 21:46:17

问题


I have a BaseActivity for all activities in my app. Here I create, add to the view hierarchy and load an AdView programmatically in onStart.

If I navigate to other activity in my app and then go back, or exit app LeakCanary report a memory leak.

In all the examples on the internet for Admob, the ad is loaded in onCreate, but we may use onStart see this and this

There is more questions about this: SO, issue BUT NOT SOLUTION.

The only solution that I found is to use onStart y onStop to use all logic for the AdView

My question is:

Is this approach OK?

Can I have another issues(appart from memory leaks) with this approach?

What is your solution for the admob memory leak??

This is an old question but still not clear answer.

I am using implementation 'com.google.android.gms:play-services-ads:18.3.0'

Here is some of my code

public abstract class BaseActivity extends AppCompatActivity
                                   implements AdmobHelp.Listener{

    @Override protected void onCreate(Bundle savedInstanceState) {
    
      mAdmobHelp = new AdmobHelp(a, this);
    }

    @Override public void onStart() {
         super.onStart();
         mAdmobHelp.onStart();
    }

   //...
}

public class AdmobHelp extends AdListener {

    AdmobHelp(Activity a, Listener l) {
        mActivity = a;
        mContext = a.getApplicationContext();
        mResources = a.getResources();
        mCb = l;
        mLinearRootContainer = a.findViewById(R.id.linear_container_admob);
        
        //call this method only once for app (variable in Application class)
        mIsInitialized = MyApplication.isInitializeAdmobDone();
    }
    
    void onStart() {
        initlzAdmobOrNo();
        showAdNoConsent();
    }

    void onStop() {
        destroyRemoveFromContainerAdView();
    }


    void onResume() {
        if(mAdView == null) mAdView.resume();
    }

    void onPause() {
         if(mAdView == null) mAdView.pause();
    }


    void onDestroy() {
        destroyAdView();//just in case
        
        mTv = null;
        mLinearRootContainer = null;
        mCb = null;
        mContext = null;
        mActivity = null;
    }
    
    private void initlzAdmobOrNo() {
        if(!mIsInitialized) {
              MobileAds.initialize(mContext, mResources.getString(R.string.admob_app_id_test));
              mIsInitialized = true;
              MyApplication.setIsInitializeAdmobDone(true);//saved in Application class
        } 
    }
    
    private void showAdNoConsent() {
        showAd(-2); //any value but not 1
    }

    private void showAd(int statusValue) {
        if(mAdView == null) {
            initNewBannerAddToContainerLoadAdd(statusValue);
        } else {
            destroyRemoveFromContainerAdView();
            initNewBannerAddToContainerLoadAdd(statusValue);
        }
    }

    private void initNewBannerAddToContainerLoadAdd(int statusValue) {
     try {
            mAdView = new AdView(mContext);
            adView.setAdUnitId(mResources.getString(R.string.admob_banner_test));
            mAdView.setAdSize(AdSize.SMART_BANNER);
            mAdView.setAdListener(this);
            mAdView.setVisibility(View.GONE);
            if (mLinearRootContainer != null)mLinearRootContainer.addView(mAdView, 0);
            AdRequest adRequest= getAdRequestWithConsent(statusValue);
            mAdView.loadAd(adRequest);
         } catch (Exception e) {}
    }
        
    private AdRequest getAdRequestWithConsent(int statusValue) {
        AdRequest.Builder builder = new AdRequest.Builder();
        if (builder != null) {
            addAllTestDevicesIfDebug(builder);
            if (statusValue == 1) {
                l("YES npa 1 *** NON_PERSONALIZE");

                Bundle extras = new Bundle();
                extras.putString("npa", "1");
                builder.addNetworkExtrasBundle(AdMobAdapter.class, extras);
            }
            AdRequest adRequest = builder.build();
            return adRequest;
        }
        return null;
    }
        
    public void destroyRemoveFromContainerAdView() {
        try {
            if (mAdView != null) {
                mAdView.pause();
                mAdView.setAdListener(null);
                if (mLinearRootContainer != null) mLinearRootContainer.removeView(mAdView);
                mAdView.destroy();
                mAdView = null;
            }
        } catch (Exception e) {}
    }
    private void destroyAdView() {
        try {
            if (mAdView != null) {
                mAdView.setAdListener(null);
                mAdView.destroy();
            }
        } catch (Exception e) {}
        mAdView = null;
    }
    
    @Override public void onAdLoaded() {
         if (mTv != null) mTv.setVisibility(View.GONE);
         if (mAdView != null) mAdView.setVisibility(View.VISIBLE);
    }
}
This are my intents to navigate


```
void makeIntentToSecondActivity(){
    Intent i = new Intent(...);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(i);
    //NOT finish()
}

void makeIntentToThirdActivity(){
    Intent i = new Intent(...);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(i);
    finish()
}



And to go back:

void makeIntentToMainActivity(){
    Intent i = new Intent(...);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(i);
    finish()
}

来源:https://stackoverflow.com/questions/65643767/android-admob-has-memory-leak

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!