Toast $ TN.mNextView的内存泄漏

时间:2018-10-19 10:38:47

标签: android memory-leaks leakcanary

我在应用程序中添加了泄漏金丝雀,并且发现了此内存泄漏:https://i.imgur.com/8nFOoH4.png

我不在MainActivity LinearLayout或Toast上使用,但是我有此泄漏,我无法理解为什么以及如何使用。也许是因为我在MainActivity中使用的切片中使用了烤面包和线性布局?

这是我的MainActivity xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/lost_connection_image_view"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/fullscreen_exit"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        android:minHeight="?attr/actionBarSize"
        android:theme="?attr/actionBarTheme"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <de.hdodenhof.circleimageview.CircleImageView
            android:id="@+id/userPhoto"
            android:layout_width="36dp"
            android:layout_height="36dp"
            android:layout_alignParentEnd="true"
            android:layout_gravity="end"
            android:layout_margin="8dp"
            android:background="@android:color/transparent"
            android:src="@drawable/account_default"
            android:visibility="visible"
            tools:layout_editor_absoluteX="312dp"
            tools:layout_editor_absoluteY="4dp"/>

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_margin="8dp"
            app:cardBackgroundColor="@android:color/background_light"
            app:cardCornerRadius="1dp"
            tools:layout_editor_absoluteX="16dp"
            tools:layout_editor_absoluteY="28dp">

            <android.support.constraint.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:focusable="true"
                android:focusableInTouchMode="true">

                <EditText
                    android:id="@+id/search_field"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="8dp"
                    android:layout_marginEnd="8dp"
                    android:layout_marginStart="8dp"
                    android:layout_marginTop="8dp"
                    android:background="@null"

                    android:ems="10"
                    android:hint="@string/search_for"
                    android:imeOptions="actionSearch"
                    android:inputType="text"
                    android:singleLine="true"
                    android:textColorHint="@android:color/darker_gray"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toStartOf="@+id/search"
                    app:layout_constraintStart_toStartOf=" parent"
                    app:layout_constraintTop_toTopOf="parent"/>

                <ImageView
                    android:id="@+id/search"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="8dp"
                    android:layout_marginTop="8dp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    app:srcCompat="@drawable/search"/>
            </android.support.constraint.ConstraintLayout>

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


    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:layout_constraintBottom_toTopOf="@+id/navigationView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar">

    </FrameLayout>

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        app:itemIconTint="@color/bottom_nav_selected"
        app:itemTextColor="@color/bottom_nav_selected"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/menu_main"/>
</android.support.constraint.ConstraintLayout>

以及我放入ID为“容器”的FrameLayout中的片段之一:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/home_fragment_root"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="0dp"
        android:layout_marginTop="0dp"
        android:layout_marginEnd="0dp"
        android:layout_marginBottom="0dp"
        android:visibility="invisible">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.constraint.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:focusable="false"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent">


                <com.bondpm.bond.customViews.WrapContentViewPager
                    android:id="@+id/viewPager"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:background="@android:color/background_light"
                    android:focusable="true"
                    android:padding="0dp"
                    app:cardBackgroundColor="@android:color/background_light"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintHorizontal_bias="0.0"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"/>

                <com.rd.PageIndicatorView
                    android:id="@+id/pageIndicatorView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:layout_marginBottom="8dp"
                    app:layout_constraintBottom_toBottomOf="@id/viewPager"
                    app:layout_constraintEnd_toEndOf="@+id/viewPager"
                    app:layout_constraintStart_toStartOf="parent"
                    app:piv_animationType="scale"
                    app:piv_dynamicCount="true"
                    app:piv_interactiveAnimation="true"
                    app:piv_viewPager="@id/viewPager"/>

            </android.support.constraint.ConstraintLayout>

            <android.support.v7.widget.RecyclerView
                android:id="@+id/home_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:nestedScrollingEnabled="false"
                android:visibility="visible"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/pageIndicatorView"/>


        </LinearLayout>
    </android.support.v4.widget.NestedScrollView>

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:indeterminate="true"/>

</RelativeLayout> 

这里的MainActivity代码:

class  MainActivity : BaseActivity(), BottomNavigationView.OnNavigationItemSelectedListener, MainActivityView.View {
    private val presenter = MainActivityPresenter()
    private val TAG = this::class.java.simpleName

    private val homeFragment = HomeFragment()
    private val exploreFragment = ExploreFragment()
    private val feedsFragment = FeedsFragment()

    private var currentTabTag = "home"

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.home -> openFragment(homeFragment, "home")
            R.id.explore -> openFragment(exploreFragment, "explore")
            R.id.feeds -> openFragment(feedsFragment, "feeds")
        }

        return true
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        presenter.attachView(this)

        if (savedInstanceState != null || !Utils.isLogined) {
            if (savedInstanceState != null) {
                currentTabTag = savedInstanceState.getString("currentTab")
                if (Utils.userInfo != null && Utils.userInfo?.data?.user?.photo != null) Glide.with(this).load(Utils.userInfo!!.data.user.photo).into(userPhoto)
                else userPhoto.setImageResource(RBase.drawable.account_default)
            }

            userPhoto.setOnClickListener {
                next()
            }

            userInterfaceInit()

        } else presenter.getUserInfo()
    }

    private fun userInterfaceInit() {
        navigationView.setOnNavigationItemSelectedListener(this)
        navigationView.menu.getItem(0).isChecked = true

//        search_field.text = SpannableStringBuilder("")
        search.setOnClickListener{
            if(search_field.text.toString() != "") {
                val intent = Intent(this, SearchActivity::class.java)
                intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
                intent.putExtra("query", search_field.text.toString())
                startActivity(intent)
            }
        }

        search_field.setOnEditorActionListener(TextView.OnEditorActionListener { _, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                if(search_field.text.toString() != "") {
                    val intent = Intent(this, SearchActivity::class.java)
                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION)
                    intent.putExtra("query", search_field.text.toString())
                    startActivity(intent)
                }
                return@OnEditorActionListener true
            }
            false
        })

        Log.d(TAG, currentTabTag)

        when (currentTabTag) {
            "home" -> openFragment(homeFragment, "home")
            "explore" -> openFragment(exploreFragment, "explore")
            "feeds" -> openFragment(feedsFragment, "feeds")
        }


        userPhoto.setOnClickListener {
            next()
        }
        setSupportActionBar(toolbar)
        supportActionBar!!.title = ""
    }

    private fun openFragment(fragment: Fragment, tag: String) {
        val transaction = fragmentManager.beginTransaction()
        transaction.replace(R.id.container, fragment, tag)
        currentTabTag = tag
        if (!isFinishing &&!isDestroyed) transaction.commitAllowingStateLoss()
    }

    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
        outState!!.putString("currentTab", currentTabTag)
    }

    override fun showUserInfo() {
        if (Utils.userInfo != null && Utils.userInfo!!.data.user.photo != null) Glide.with(this).load(Utils.userInfo!!.data.user.photo).into(userPhoto)
        else userPhoto.setImageResource(RBase.drawable.account_default)
        userInterfaceInit()
    }

    override fun showMessage(resId: Int) {
        //Toast.makeText(applicationContext, resId, Toast.LENGTH_LONG).show()
    }

    override fun onDestroy() {
        super.onDestroy()
        presenter.detachView()
        presenter.destroy()
    }

1 个答案:

答案 0 :(得分:0)

看起来您的吐司寿命比父母的寿命长。尝试将应用程序用作上下文。就像在您的注释代码中一样:

Toast.makeText(applicationContext, resId, Toast.LENGTH_LONG).show()