У меня есть MainActivity, которая имеет customView (DatePicker) в своем макете. Пользовательский вид DatePicker имеет кнопку и CustomDialogFragment. Когда кнопка нажата на DatePicker, он показывает CustomDialogFragment. Приложение работает нормально, но leakCanary показывает утечку. Вот код (Некоторый код удален для краткости)
MainActivity.class
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
date_picker.calendarDialog = getCalendarDialog()
}
private fun getCalendarDialog(): CalendarDialog {
return CalendarDialog()
}
}
activity_main. xml
<androidx.constraintlayout.widget.ConstraintLayout>
<com.example.testproject.customViews.DatePicker
android:id="@+id/date_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</com.example.testproject.customViews.DatePicker>
</androidx.constraintlayout.widget.ConstraintLayout>
DatePicker.class
class DatePicker : FrameLayout {
var calendarDialog: CalendarDialog? = null
init {
View.inflate(context, R.layout.date_picker, this)
open_calendar.setOnClickListener {
calendarDialog?.show((context as MainActivity).supportFragmentManager.beginTransaction(), "Calendar")
}
}
}
CalendarDialog.class
class CalendarDialog: DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val builder = AlertDialog.Builder(context!!)
builder.setView(view)
.setMessage("This is a dummy message")
.setPositiveButton("OK") { dialog, which -> }
.setNegativeButton("Cancel") { dialog, which -> }
return builder.create()
}
}
РЕЗУЛЬТАТ АНАЛИЗА КАРТЫ ============================ ====== 1 УТВЕРЖДЕНИЕ ПРИЛОЖЕНИЯ
References underlined with "~~~" are likely causes.
Learn more at https://squ.re/leaks.
1437 bytes retained by leaking objects
Signature: 1eb8b5c7c3fd403a9a6851729c4044c8a6ce7cf6
┬───
│ GC Root: System class
│
├─ android.view.inputmethod.InputMethodManager class
│ Leaking: NO (InputMethodManager↓ is not leaking and a class is never leaking)
│ ↓ static InputMethodManager.sInstance
├─ android.view.inputmethod.InputMethodManager instance
│ Leaking: NO (DecorView↓ is not leaking and InputMethodManager is a singleton)
│ ↓ InputMethodManager.mNextServedView
├─ com.android.internal.policy.DecorView instance
│ Leaking: NO (LinearLayout↓ is not leaking and View attached)
│ mContext instance of com.android.internal.policy.DecorContext, wrapping activity com.example.testproject.MainActivity with mDestroyed = false
│ Parent android.view.ViewRootImpl not a android.view.View
│ View#mParent is set
│ View#mAttachInfo is not null (view attached)
│ View.mWindowAttachCount = 1
│ ↓ DecorView.mContentRoot
├─ android.widget.LinearLayout instance
│ Leaking: NO (MainActivity↓ is not leaking and View attached)
│ mContext instance of com.example.testproject.MainActivity with mDestroyed = false
│ View.parent com.android.internal.policy.DecorView attached as well
│ View#mParent is set
│ View#mAttachInfo is not null (view attached)
│ View.mWindowAttachCount = 1
│ ↓ LinearLayout.mContext
├─ com.example.testproject.MainActivity instance
│ Leaking: NO (DatePicker↓ is not leaking and Activity#mDestroyed is false)
│ ↓ MainActivity._$_findViewCache
├─ java.util.HashMap instance
│ Leaking: NO (DatePicker↓ is not leaking)
│ ↓ HashMap.table
├─ java.util.HashMap$Node[] array
│ Leaking: NO (DatePicker↓ is not leaking)
│ ↓ HashMap$Node[].[0]
├─ java.util.HashMap$Node instance
│ Leaking: NO (DatePicker↓ is not leaking)
│ ↓ HashMap$Node.value
├─ com.example.testproject.customViews.DatePicker instance
│ Leaking: NO (View attached)
│ mContext instance of com.example.testproject.MainActivity with mDestroyed = false
│ View.parent androidx.constraintlayout.widget.ConstraintLayout attached as well
│ View#mParent is set
│ View#mAttachInfo is not null (view attached)
│ View.mID = R.id.date_picker
│ View.mWindowAttachCount = 1
│ ↓ DatePicker.calendarDialog
│ ~~~~~~~~~~~~~~
╰→ com.example.testproject.customViews.CalendarDialog instance
Leaking: YES (ObjectWatcher was watching this because com.example.testproject.customViews.CalendarDialog received Fragment#onDestroy() callback and Fragment#mFragmentManager is null)
key = e176896c-49c6-4b17-a21e-4a6ca7cde260
watchDurationMillis = 11213
retainedDurationMillis = 6208
key = f3a2f22a-c77f-4c8e-a281-d803d110acff
watchDurationMillis = 11214
====================================
0 LIBRARY LEAKS
Library Leaks are leaks coming from the Android Framework or Google libraries.
====================================
METADATA
Please include this in bug reports and Stack Overflow questions.
Build.VERSION.SDK_INT: 28
Build.MANUFACTURER: Google
LeakCanary version: 2.2
App process name: com.example.testproject
Analysis duration: 4191 ms
Heap dump file path: /data/user/0/com.example.testproject/files/leakcanary/2020-03-11_10-15-46_729.hprof
Heap dump timestamp: 1583936152876
====================================
Это то, что я пытался до сих пор безуспешно.
- Я пытался инициализировать CalendarDialog в разных местах.
- Создайте прослушиватель в классе CalendarDialog и сделайте экземпляр calendarDialog пустым при закрытии диалога. И еще немного ..