AdActivity leak on AdMob (SDK 7.0) for Android

馋奶兔 提交于 2019-12-23 09:27:35

问题


I have memory leaks regarding Interstitial ads of AdMob with AdActivity object. Whenever an ad is shown, AdActivity object count in the memory increments by 1. I inspect all changes via MAT after explicit GC calls. I use the latest versions of everything.

At first, I thought that this is related to how I implemented my UI or project, but creating a fresh and empty project shows the same leak.

This leak has also existed in the previous Admob SDK (Google Play Services) and now it exists in version 7.0 too.

I see that people try to solve these kinds of issues by creating a SingleInstance empty activity just to show and set as the context of the interstitial ads. I tried them all and they did not work for my case. Some did help but I even couldn't use it because of the flow of my app. launchMode in Android has limitations and it does not help me on my case.

I already notified the AdMob team but even they fix it, it doesn't seem to happen in a short time as they have just released the version 7.0 SDK.

I do not understand how others do not report leaks like this. It cannot be a special case just for me as it happens on even samples or default templates. If anyone somehow solved this issue (including ugly reflection hacks) please share your experience. I have been working on this for months! Really!

AndroidManifest:

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="22" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
    android:name="MyApplication"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name="com.google.android.gms.ads.AdActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
        android:theme="@android:style/Theme.Translucent" />
</application>

MainActivity:

package com.example.leaktest1;

import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;

import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {

    private InterstitialAd interstitial=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        interstitial= new InterstitialAd(getApplicationContext());
        interstitial.setAdUnitId("YOUR-ADD-ID");

        AdRequest adRequest2 = new AdRequest.Builder()
        // .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
                .build();

        interstitial.setAdListener(new AdListener() {
            @Override
            public void onAdLoaded() {          
                super.onAdLoaded();

                if(interstitial.isLoaded()){
                    interstitial.show();
                }
            }
        });
        interstitial.loadAd(adRequest2);
    }


    @Override
    protected void onDestroy() {
        if(interstitial!=null){
            interstitial.setAdListener(null);
            interstitial=null;
        }
        super.onDestroy();
    }     
}

Layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.leaktest1.MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>
  • Start the app. When the ad is shown, close it with backpress and hit back button again to exit app.
  • App will still be in memory, but the activity is gone. Now touch the app icon to start the activity again, it will show the ad again, exit like you did before.
  • Cause GC multiple times and get heap dump. You will see that there are 2 AdActivity objects (and also many other related objects). It will continue to grow according to the number of shown ads.

The following did not work too (it still leaks):

/*
interstitial.setAdListener(new AdListener() {
    @Override
    public void onAdLoaded() {          
        super.onAdLoaded();
    }
});*/
interstitial.loadAd(adRequest2);

Runnable r=new Runnable() {
    @Override
    public void run() {
                if(interstitial.isLoaded()){
                    interstitial.show();
                }
}};
new Handler().postDelayed(r,10000);

And putting code inside a button did not work too (it still leaks):

Button b = new Button(this);
b.setText("Touch me");
b.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        if(interstitial.isLoaded()){
            interstitial.show();
        }
    }
});
ViewGroup v = (ViewGroup) this.findViewById(android.R.id.content);
v.addView(b);

Leak platform and exceptions: This leak happens on various devices from Samsung and Asus with various un-modded (original firmware) Androis systems from 2.3 to 4.4. It also happens on any setup of android simulator.

(This leak does not show up on rooted Cyanogenmod (Galaxy S3) Android 4.4.4)

UPDATE

The leak does not vanish if I use Activity context instead of Application context. It also causes Activity leak too.

来源:https://stackoverflow.com/questions/29252545/adactivity-leak-on-admob-sdk-7-0-for-android

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