Leakcanary显示了AppCompatActivity和FragmentStatePagerAdapter片段泄漏 [英] Leakcanary shows fragment leak with AppCompatActivity and FragmentStatePagerAdapter

查看:1749
本文介绍了Leakcanary显示了AppCompatActivity和FragmentStatePagerAdapter片段泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在有这个问题了一会儿,我真的不知道还有什么尝试。我坚持Leakcanary在我的项目,所以我可以强迫自己去学习Android的正确的方式不拿起导致内存泄漏的模式..我建立一个应用程序,我已经剥离下来了很多,我仍然看到此泄漏发生。

我有内部有一个viewpager和实例10片段的活动。如果我打开设备似乎一切都很好,这是直到我美元家,我得到了以下的内存泄漏p $ PSS:

  D / LeakCanary:在com.doesnthaveadomain.leo.calendartracker:1.0:1。
D / LeakCanary:* com.doesnthaveadomain.leo.calendartracker.MyFragment渗漏:
D / LeakCanary:* GC ROOT静态android.view.WindowManagerGlobal.sDefaultWindowManager
D / LeakCanary:*引用android.view.WindowManagerGlobal.mRoots
D / LeakCanary:*引用java.util.ArrayList.array
D / LeakCanary:*参考阵列的java.lang.Object [] [0]
D / LeakCanary:*引用android.view.ViewRootImpl.mInvalidateOnAnimationRunnable
D / LeakCanary:*引用android.view.ViewRootImpl $ InvalidateOnAnimationRunnable.mViews
D / LeakCanary:*引用java.util.ArrayList.array
D / LeakCanary:*参考阵列的java.lang.Object [] [0]
D / LeakCanary:*引用android.support.v4.view.ViewPager.mAdapter
D / LeakCanary:*引用com.doesnthaveadomain.leo.calendartracker.MyAdapter.mCurrentPrimaryItem
D / LeakCanary:*泄漏com.doesnthaveadomain.leo.calendartracker.MyFragment实例

MainActivity:

 进口android.os.Bundle;
进口android.support.v4.app.Fragment;
进口android.support.v4.app.FragmentManager;
进口android.support.v4.app.FragmentStatePagerAdapter;
进口android.support.v4.view.ViewPager;
进口android.support.v7.app.AppCompatActivity;进口java.lang.ref.WeakReference;公共类MainActivity扩展AppCompatActivity {    @覆盖
    保护无效的onCreate(捆绑savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);        ViewPager mViewPager =(ViewPager)findViewById(R.id.viewpager);
        MyAdapter myAdapter =新MyAdapter(getSupportFragmentManager(),这一点);
        mViewPager.setAdapter(myAdapter);
        mViewPager.setCurrentItem(5);
    }}类MyAdapter扩展FragmentStatePagerAdapter {    私人诠释mNumberOfViews;
    私人最终的WeakReference< AppCompatActivity> mActivityWeakRef;    公共MyAdapter(FragmentManager FM,
                     AppCompatActivity活动){
        超(FM);        mActivityWeakRef =新的WeakReference< AppCompatActivity>(活动);
        mNumberOfViews = 10;
    }    @覆盖
    公共片段的getItem(INT位置){
        MyFragment myFragment =新MyFragment();
        AppCompatActivity活性= mActivityWeakRef.get();
        如果(活动!= NULL){
            。MyApp.getRefWatcher(mActivityWeakRef.get())腕表(myFragment);
        }
        返回myFragment;
    }    @覆盖
    公众诠释的getCount(){
        返回mNumberOfViews;
    }
}

MainActivity布局:

 <的LinearLayout
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直
    的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android>    < android.support.design.widget.AppBarLayout
        的xmlns:程序=htt​​p://schemas.android.com/apk/res-auto
        的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
        机器人:ID =@ + ID / toolbar_appbar_layout
        机器人:layout_width =match_parent
        机器人:layout_height =WRAP_CONTENT
        机器人:fitsSystemWindows =真正的>        < android.support.v7.widget.Toolbar
            机器人:ID =@ + ID /工具栏
            机器人:layout_width =match_parent
            机器人:layout_height =?ATTR / actionBarSize
            机器人:ATTR / colorPrimary背景=
            应用:layout_scrollFlags =滚动| enterAlways
            应用:主题=@风格/ AppTheme.Toolbar
            应用:popupTheme =@风格/ AppTheme.Toolbar.Popup>        < /android.support.v7.widget.Toolbar>    < /android.support.design.widget.AppBarLayout>    < android.support.v4.view.ViewPager
        机器人:ID =@ + ID / viewpager
        机器人:layout_width =match_parent
        机器人:layout_height =match_parent/>< / LinearLayout中>

片段:

 进口android.os.Bundle;
进口android.support.v4.app.Fragment;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.ViewGroup;/ **
 *包含一个简单视图中的占位符片段。
 * /
公共类MyFragment扩展片段{    @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
                             捆绑savedInstanceState){
        返回inflater.inflate(R.layout.fragment_test,集装箱,FALSE);
    }}

片段布局:

 <的LinearLayout
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直
    机器人:paddingLeft =@扪/ activity_vertical_margin
    机器人:paddingStart =@扪/ activity_vertical_margin
    机器人:paddingRight =@扪/ activity_vertical_margin
    机器人:paddingEnd =@扪/ activity_vertical_margin
    的xmlns:程序=htt​​p://schemas.android.com/apk/res-auto
    的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android>< / LinearLayout中>


解决方案

同样的问题作为我的另一个问题,我在错误的时间初始化裁判守望者,在创作的片段,而不是在破坏:<一href=\"http://stackoverflow.com/a/32881096/5278339\">http://stackoverflow.com/a/32881096/5278339

I've been having this issue for a while now and I really don't know what else to try. I've stuck Leakcanary on my project so I can force myself to learn android 'the right way' without picking up patterns that cause memory leaks.. I'm building an app and I've stripped it down a lot and I still see this leak happening.

I have an Activity which has a viewpager inside and instantiates 10 fragments. If I turn the device everything seems fine, it's not until I press on 'Home' that I get the following memory leak:

D/LeakCanary﹕ In com.doesnthaveadomain.leo.calendartracker:1.0:1.
D/LeakCanary﹕ * com.doesnthaveadomain.leo.calendartracker.MyFragment has leaked:
D/LeakCanary﹕ * GC ROOT static android.view.WindowManagerGlobal.sDefaultWindowManager
D/LeakCanary﹕ * references android.view.WindowManagerGlobal.mRoots
D/LeakCanary﹕ * references java.util.ArrayList.array
D/LeakCanary﹕ * references array java.lang.Object[].[0]
D/LeakCanary﹕ * references android.view.ViewRootImpl.mInvalidateOnAnimationRunnable
D/LeakCanary﹕ * references android.view.ViewRootImpl$InvalidateOnAnimationRunnable.mViews
D/LeakCanary﹕ * references java.util.ArrayList.array
D/LeakCanary﹕ * references array java.lang.Object[].[0]
D/LeakCanary﹕ * references android.support.v4.view.ViewPager.mAdapter
D/LeakCanary﹕ * references com.doesnthaveadomain.leo.calendartracker.MyAdapter.mCurrentPrimaryItem
D/LeakCanary﹕ * leaks com.doesnthaveadomain.leo.calendartracker.MyFragment instance

MainActivity:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;

import java.lang.ref.WeakReference;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ViewPager mViewPager = (ViewPager) findViewById(R.id.viewpager);
        MyAdapter myAdapter = new MyAdapter(getSupportFragmentManager(), this);
        mViewPager.setAdapter(myAdapter);
        mViewPager.setCurrentItem(5);
    }

}

class MyAdapter extends FragmentStatePagerAdapter {

    private int mNumberOfViews;
    private final WeakReference<AppCompatActivity> mActivityWeakRef;

    public MyAdapter(FragmentManager fm,
                     AppCompatActivity activity) {
        super(fm);

        mActivityWeakRef = new WeakReference<AppCompatActivity>(activity);
        mNumberOfViews = 10;
    }

    @Override
    public Fragment getItem(int position) {
        MyFragment myFragment = new MyFragment();
        AppCompatActivity activity = mActivityWeakRef.get();
        if (activity != null) {
            MyApp.getRefWatcher(mActivityWeakRef.get()).watch(myFragment);
        }
        return myFragment;
    }

    @Override
    public int getCount() {
        return mNumberOfViews;
    }
}

MainActivity Layout:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <android.support.design.widget.AppBarLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbar_appbar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true" >

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:theme="@style/AppTheme.Toolbar"
            app:popupTheme="@style/AppTheme.Toolbar.Popup">

        </android.support.v7.widget.Toolbar>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

Fragment:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A placeholder fragment containing a simple view.
 */
public class MyFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_test, container, false);
    }

}

Fragment Layout:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_vertical_margin"
    android:paddingStart="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_vertical_margin"
    android:paddingEnd="@dimen/activity_vertical_margin"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">

</LinearLayout>

解决方案

Same problem as my other issue, I was initializing the ref watcher at the wrong time, on fragment creation instead of on destroy: http://stackoverflow.com/a/32881096/5278339

这篇关于Leakcanary显示了AppCompatActivity和FragmentStatePagerAdapter片段泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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