Android的AdMob的会导致内存泄漏? [英] Android AdMob causes memory leak?

查看:426
本文介绍了Android的AdMob的会导致内存泄漏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经集成AdMob的V4.1.0到我的应用程序,它似乎已经造成了严重的内存泄露(pretty的肯定,这已经发生在4.0.4)。

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).

为了隔离我创建了一个新的项目,一个空白的线性布局,并增加了AD浏览报给它的问题(其实这是一个复制和;从AdMob的提供的样品code粘贴)。见我main.xml中,MainActivity.java和清单的内容:

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中:

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:

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

清单:

<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" />

这就是所有的code我。

And that's all the code I have.

现在,运行该应用程序时,我可以看到,无论在onPause和onDestory被调用,该项活动已经终止,但问题是,它永远不会适用于GC,因为它会导致InputMethodManager举行引用活动(请参阅从HPROF输出拍摄的图像的活性被破坏后):

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):

在我删除AD浏览报相关的code(并再次,这是该应用程序的仅code)该问题消失:

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

编辑: 还试图从的onCreate删除所有code和更新的main.xml包含以下(仍然得到同样的结果):

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 ????

推荐答案

下面是我的工作,围绕这个烂摊子:

Here is my work around for this mess:

我已经限制了内存泄漏,使用相同的空活动实例:

I've limited the memory leak, by using the same empty activity instance:

public final class AdMobActivity
        extends Activity {

    public static AdMobActivity AdMobMemoryLeakWorkAroundActivity;

    public AdMobActivity() {
        super();
        if (AdMobMemoryLeakWorkAroundActivity != null)
            throw new IllegalStateException("This activity should be created only once during the entire application life");
        AdMobMemoryLeakWorkAroundActivity = this;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        finish();
    }

    public static final void startAdMobActivity(Activity activity) {
        Intent i = new Intent();
        i.setComponent(new ComponentName(activity.getApplicationContext(), AdMobActivity.class));
        activity.startActivity(i);
    }
}

另外广告将使用创建的 AdMobActivity.AdMobMemoryLeakWorkAroundActivity

您还需要将活动添加到课程的清单:

You also need to add the activity to the manifest of course:

<activity
    android:launchMode="singleInstance"
    android:name="com.nu.art.software.android.modules.admob.AdMobActivity" />

本实施违背我的信仰有关静态引用,而不是常量,但这种实现prevents泄漏,因为只有一个活动实例用于创建所有的广告,因此没有更多的活动泄漏,加上事实该活动完全是空的。

This implementation goes against my beliefs regarding static references, which are not constants, but this implementation prevents the leak because only one activity instance is used to create all the ads, and so no more activity leaks, plus the fact that the activity is completely empty.

注意:您应该叫 startAdMobActivity 从应用程序的主要活动方式的onCreate 方式

NOTE: You should call the startAdMobActivity method from the application main activity onCreate method.

亚当。

更新

该解决方案只有当你动态创建的广告,并将其添加到与code中的布局......不要忘记去破坏它在Activity.onDestroy()。

This solution works only if you create the ad dynamically, and add it to the layout with code... and don't forget to destroy it in the Activity.onDestroy().

这篇关于Android的AdMob的会导致内存泄漏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆