我在一个由片段创建的窗口中显示一个AdMob广告横幅。这行得通,但我有奇怪的泄漏问题,我还不明白。当我多次打开和关闭应用程序时,每次都会正确销毁广告片段,但控制此片段的主活动正在泄漏:
有罪的是代码中的这一行:

adRequest = new AdRequest.Builder().addTestDevice(DEVICE_ID_MOTO_G).addTestDevice(DEVICE_ID_ZTE).build();
mAdView.loadAd(adRequest);

(您可以在下面看到,我已经试图取消地址请求,但没有结果。)无论如何,当我评论这两行时,不会发生泄漏。我测试了两次,因为很难相信这个调用会泄漏,但它确实泄漏了。这是片段代码。如您所见,我甚至取消了onDestroy()中所有可能的内容。我可以保证onDestroy()被调用。loadAd启动任何背景线程。我想这和那个问题有关。
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();
    }
}

最佳答案

我幸运地找到了解决办法。在碎片被销毁之前,您必须手动将adview从周围的布局中踢出。在我启动并关闭应用程序大约20次之后,就再也没有泄漏了。以下是更新的片段:

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 - Android AdView泄漏,可能是由于某些内部后台线程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28727483/

10-09 06:52
查看更多