Android AdMob causes memory leak?

2019-01-17 07:34发布

I've integrated AdMob v4.1.0 into my application and it seems to have caused a huge memory leak (pretty sure that it already happened on 4.0.4).

In order to isolate the problem I created a new project with a blank linear layout and added the AdView to it (this is actually a copy&paste from the sample code provided by AdMob). See my main.xml, MainActivity.java and manifest content:

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/linearLayout">
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
</LinearLayout>

MainActivity.java:

package AdsTry.main;

import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

    private final int AD_VIEW_ID = 1000000; 

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

         // Lookup R.layout.main
        LinearLayout layout = (LinearLayout)findViewById(R.id.linearLayout);

        // Create the adView
        // Please replace MY_BANNER_UNIT_ID with your AdMob Publisher ID
        AdView adView = new AdView(this, AdSize.BANNER, "MY_BANNER_UNIT_ID");
        adView.setId(AD_VIEW_ID);

        // Add the adView to it
        layout.addView(adView);

        // Initiate a generic request to load it with an ad
        AdRequest request = new AdRequest();

        adView.loadAd(request);           
    }

    @Override
    protected void onPause() {
        Log.i("AdsTry", "onPause");

        getAdView().stopLoading();

        super.onPause();
    }

    @Override
    protected void onDestroy() {
        Log.i("AdsTry", "onDestroy");

        getAdView().destroy();

        super.onDestroy();
    }

    private AdView getAdView()
    {
        return (AdView) findViewById(AD_VIEW_ID);
    }
}

manifest:

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <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>

    <!-- AdMobActivity definition -->
    <activity android:name="com.google.ads.AdActivity"
        android:configChanges="orientation|keyboard|keyboardHidden" />
</application>

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

And that's all the code I have.

Now, when running this application, I can see that both onPause and onDestory are called and the Activity is terminated, BUT the problem is that it will never be available for the GC since it causes the InputMethodManager to hold a reference to the Activity (See image taken from HPROF output after the activity was destroyed): MainActivity Merge shortest path to GC Roots

Once I remove the AdView-related code (and again, this is the ONLY code of this application) the problem goes away: Same HPROF output without using AdView

EDIT: Also tried removing ALL the code from onCreate and updated the main.xml to contain the following (still get the same result):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/linearLayout">
    <TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />
    <com.google.ads.AdView
    android:id="@+id/Ad"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    ads:adUnitId="MY_ID"
    ads:adSize="BANNER"
    ads:loadAdOnCreate="true"/>
</LinearLayout>

Any ideas ????

8条回答
聊天终结者
2楼-- · 2019-01-17 08:01

I found out that calling:-

mAdView.destroy(); 

before leaving the activity solves the leak for me.

Here is how I declare the banner ads in xml:-

  <com.google.android.gms.ads.AdView
            android:id="@+id/adView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal|bottom"
            ads:adSize="BANNER"
            ads:adUnitId="@string/banner_ad_unit_id_2" />

Get a reference to admob banner in onCreate():-

mAdView = (AdView) findViewById(R.id.adView2);
AdRequest banneradRequest = new AdRequest.Builder().build();

mAdView.loadAd(banneradRequest);

and destroy it in ondestroy() of the activity:-

@Override
protected void onDestroy() {
    super.onDestroy();
    mAdView.destroy();
}
查看更多
不美不萌又怎样
3楼-- · 2019-01-17 08:01

I'm facing the same issue. The only one thing helped me - its System.exit(0). I don't like it but it is the only way i've found.
AdMob just stays in RAM 4ever and don't let my app to finish properly. When i restart my app OS just raises that undead app and soon it causes the out of memory exception.
My AdMob support forum topic - no support so far. Looks like no1 cares.

查看更多
登录 后发表回答