Muz*_*ant 21 memory android memory-leaks admob
我已将AdMob v4.1.0集成到我的应用程序中,它似乎导致了巨大的内存泄漏(非常确定它已经发生在4.0.4上).
为了隔离问题,我创建了一个具有空白线性布局的新项目,并向其添加了AdView(这实际上是AdMob提供的示例代码中的复制和粘贴).请参阅我的main.xml,MainActivity.java和清单内容:
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>
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
表现:
<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" />
Run Code Online (Sandbox Code Playgroud)
这就是我所拥有的所有代码.
现在,在运行此应用程序时,我可以看到onPause和onDestory都被调用并且Activity被终止,但问题是它将永远不可用于GC,因为它导致InputMethodManager保存对Activity的引用(参见活动被销毁后从HPROF输出中获取的图像):
删除与AdView相关的代码后(再次,这是此应用程序的唯一代码)问题就消失了:
编辑:还尝试从onCreate中删除所有代码并更新main.xml以包含以下内容(仍然得到相同的结果):
<?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>
Run Code Online (Sandbox Code Playgroud)
有任何想法吗 ????
我正在使用"play-services-ads:7.5.0",并且创建de AdMobActivity并不是必需的.它的工作原理是:
以动态方式创建adView
mAdView = new AdView(getApplicationContext(), AdSize.BANNER, banner_ad_unit_id); mAdsContainer.addView(mAdView);
Run Code Online (Sandbox Code Playgroud)
在销毁和销毁adView时从linearLayout中删除所有视图
mAdView.setAdListener(null);
mAdsContainer.removeAllViews();
mAdView.destroy();
Run Code Online (Sandbox Code Playgroud)
不幸的是,间隙仍在泄漏
这是我为这个烂摊子做的工作:
我通过使用相同的空活动实例来限制内存泄漏:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
将使用AdMobActivity.AdMobMemoryLeakWorkAroundActivity创建更多广告.
您还需要将活动添加到清单中:
<activity
android:launchMode="singleInstance"
android:name="com.nu.art.software.android.modules.admob.AdMobActivity" />
Run Code Online (Sandbox Code Playgroud)
这种实现违背了我对静态引用的看法,静态引用不是常量,但是这种实现可以防止泄漏,因为只有一个活动实例用于创建所有广告,因此没有更多活动泄漏,加上活动完全为空.
注意:您应该从应用程序主要活动onCreate方法调用startAdMobActivity方法.
亚当.
UPDATE
此解决方案仅在您动态创建广告时才有效,并使用代码将其添加到布局中...并且不要忘记在Activity.onDestroy()中将其销毁.
Sun*_*hoo -1
不要将您的 UI 与 Admob 合并,您可以运行另一个线程从 Admob 获取广告。您还可以在特定的时间间隔刷新广告。这样您就可以更轻松地调试内存问题所在的位置。
谢谢迪帕克
归档时间: |
|
查看次数: |
9984 次 |
最近记录: |