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()
}
from Memory Leak at Toast$TN.mNextView
No comments:
Post a Comment