Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory Leak at Toast$TN.mNextView

I add leak canary to my app and I find this memory leak: https://i.imgur.com/8nFOoH4.png

I don't use at my MainActivity LinearLayout or Toast but I has this leak and I can't understand why and how. Maybe it because I use toasts and linear layout inside fragments that I use in MainActivity?

Here is my 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>

And one of fragments that I put in FrameLayout with id "container":

<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> 

Here MainActivity code:

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()
    }
like image 847
Vlad Kramarenko Avatar asked Oct 19 '18 10:10

Vlad Kramarenko


People also ask

What is the main cause of memory leaks?

DEFINITION A memory leak is the gradual deterioration of system performance that occurs over time as the result of the fragmentation of a computer's RAM due to poorly designed or programmed applications that fail to free up memory segments when they are no longer needed.

How do I find a memory leak?

To find a memory leak, look at how much RAM the system is using. The Resource Monitor in Windows can be used to accomplish this. In Windows 8.1 and Windows 10: To open the Run dialogue, press Windows+R, then type "resmon" and click OK.

Is memory leak serious?

Very dangerous. Memory leaks in the kernel level lead to serious system stability issues. Kernel memory is very limited compared to user land memory and should be handled cautiously. Memory is allocated but never freed.

Do memory leaks cause permanent damage?

Physical or permanent damage does not happen from memory leaks. Memory leaks are strictly a software issue, causing performance to slow down among applications within a given system. It should be noted a program taking up a lot of RAM space is not an indicator that memory is leaking.


1 Answers

Looks like your toast lived longer than parent activity. Try to use Application as a Context. Like in your commented code:

Toast.makeText(applicationContext, resId, Toast.LENGTH_LONG).show()
like image 129
ckesc Avatar answered Oct 02 '22 10:10

ckesc