Android AdView leaking, probably due to some internal background thread(Android AdView 泄漏,可能是由于一些内部后台线程)
问题描述
I display an AdMob ad banner within a window created by a fragment. This works, but I'm getting strange leaking problems I don't understand yet. When I open and close the app a lot of times, the ad fragment is properly destroyed every time, but the MainActivity which controls this fragment is leaking:
The guilty one is this line in code:
adRequest = new AdRequest.Builder().addTestDevice(DEVICE_ID_MOTO_G).addTestDevice(DEVICE_ID_ZTE).build();
mAdView.loadAd(adRequest);
(You can see below that I already tried to nullify the adRequest, but no result.) Anyway, when I comment these two lines, the leaks don't occur. I tested it twice, because it was hard to believe that this invocation leaks, but it does. Here is the fragment code. As you can see, I even nullify everything that is possible in onDestroy()
. I can assure that onDestroy()
is called. loadAd
starty any background thread. I guess that has to do with that problem.
public class SnippetFragment extends Fragment
{
private AdView mAdView;
private OnAdFinishedLoadingListener onAdFinishedLoadingListener;
private Context context;
private AdRequest adRequest;
private final String DEVICE_ID_ZTE = "1CA20334345BB1479C43692AFA576456487A48";
private final String DEVICE_ID_MOTO_G = "131465469A7BE11543543065404B168908CB13C8D1";
public SnippetFragment(Context context)
{
this.context = context;
}
@Override
public void onActivityCreated(Bundle bundle)
{
super.onActivityCreated(bundle);
mAdView = (AdView)getView().findViewById(R.id.adView);
mAdView.setAdListener(new AdListener()
{
@Override
public void onAdLoaded()
{
super.onAdLoaded();
if (context != null)
{
onAdFinishedLoadingListener = (OnAdFinishedLoadingListener)context;
onAdFinishedLoadingListener.onAdLoaded();
}
}
});
//THIS SOMEHOW LEAKS!
adRequest = new AdRequest.Builder().addTestDevice(DEVICE_ID_MOTO_G).addTestDevice(DEVICE_ID_ZTE).build();
mAdView.loadAd(adRequest);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_snippet, container, false);
}
/** Called when leaving the activity */
@Override
public void onPause()
{
if (mAdView != null)
{
mAdView.pause();
}
super.onPause();
}
/** Called when returning to the activity */
@Override
public void onResume()
{
super.onResume();
if (mAdView != null)
{
mAdView.resume();
}
}
/** Called before the activity is destroyed */
@Override
public void onDestroy()
{
adRequest = null;
if (mAdView != null)
{
mAdView.setAdListener(null);
mAdView.destroy();
mAdView = null;
}
context = null;
super.onDestroy();
}
}
I fortunately found the solution. You have to manually kick the AdView out of the surrounding layout, before the fragment gets destroyed. No leak anymore after I launched and closed the app about 20 times. Here is the updated fragment:
public class SnippetFragment extends Fragment
{
private AdView adView;
private OnAdFinishedLoadingListener onAdFinishedLoadingListener;
private Context context;
private LatLng routeDestination;
private AdRequest adRequest;
private LinearLayout snippetContent;
private final String DEVICE_ID_ZTE = "2353496z35752t3524267854";
private final String DEVICE_ID_MOTO_G = "4568735862378523675427897";
@Override
public void onActivityCreated(Bundle bundle)
{
super.onActivityCreated(bundle);
snippetContent = (LinearLayout)getView().findViewById(R.id.snippet_content);
adView = (AdView)getView().findViewById(R.id.adView);
adView.setAdListener(new AdListener()
{
@Override
public void onAdLoaded()
{
super.onAdLoaded();
if (context != null)
{
onAdFinishedLoadingListener = (OnAdFinishedLoadingListener)getActivity();
onAdFinishedLoadingListener.onAdLoaded();
}
}
});
adRequest = new AdRequest.Builder().addTestDevice(DEVICE_ID_MOTO_G).addTestDevice(DEVICE_ID_ZTE).build();
adView.loadAd(adRequest);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_snippet, container, false);
}
@Override
public void onPause()
{
if (adView != null)
{
adView.pause();
}
super.onPause();
}
@Override
public void onResume()
{
super.onResume();
if (adView != null)
{
adView.resume();
}
}
@Override
public void onDestroy()
{
destroyAdView();
super.onDestroy();
}
private void destroyAdView()
{
if (adView != null)
{
adRequest = null;
adView.removeAllViews();
adView.setAdListener(null);
adView.destroy();
snippetContent.removeView(adView);
adView = null;
snippetContent = null;
}
}
}
这篇关于Android AdView 泄漏,可能是由于一些内部后台线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Android AdView 泄漏,可能是由于一些内部后台线程
基础教程推荐
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01