@Lordao

Как исправить утечку памяти при отображении DialogFragment?

Отображение фрагментов происходит таким образом:
Activity - NavigationFragment - TestFragment

В TestFragment по нажатию на кнопку выводится DialogFragment с чекбоксами. На этом моменте происходит утечка памяти.

Каким образом может исправить memory leaks?

TestFragment

package com.example.test.fragments

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.layout_first.*
import com.example.test.R

class TestFragment : Fragment() {

    private var multiDialogFragment: SelectListDialog? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? = inflater.inflate(R.layout.layout_first, container, false)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        button.setOnClickListener {
            if (multiDialogFragment == null) {
                multiDialogFragment = SelectListDialog.newInstance(arrayListOf("1", "2", "3"))
                multiDialogFragment?.setTargetFragment(this, SelectListDialog.REQUEST_CODE)
            }

            multiDialogFragment?.show(requireFragmentManager(), TAG)
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == SelectListDialog.REQUEST_CODE) {
            val list = data?.extras?.getStringArrayList(SelectListDialog.LIST)?.toMutableList()
                    ?: arrayListOf()
            Log.d("result", list.toString())
        }
    }

    override fun onDestroyView() {
        button.setOnClickListener(null)
        multiDialogFragment?.dismiss()
        super.onDestroyView()
    }

    companion object {
        const val TAG = "Fragment"
        fun newInstance() = TestFragment()
    }
}


SelectListDialog

package com.example.test

import android.app.AlertDialog
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import org.jetbrains.anko.bundleOf

class SelectListDialog : DialogFragment() {

    private var list: ArrayList<String> = arrayListOf()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments.let {
            list = it?.getStringArrayList(LIST) as ArrayList<String>
        }
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val selectedItems = ArrayList<String>()
        val builder = AlertDialog.Builder(targetFragment?.activity)
        builder.setTitle("List of strings")
                .setMultiChoiceItems(list.toTypedArray(), null) { _, which, isChecked ->
                    if (isChecked) {
                        selectedItems.add(list[which])
                    } else if (selectedItems.contains(list[which])) {
                        selectedItems.remove(list[which])
                    }
                }
                .setPositiveButton("Okay") { dialog, _ ->
                    val intent = Intent().putExtra(LIST, selectedItems)
                    targetFragment?.onActivityResult(targetRequestCode, REQUEST_CODE, intent)
                    dialog.dismiss()
                }
                .setNegativeButton("Cancel") { dialog, _ ->
                    dialog.dismiss()
                }
        return builder.create()
    }

    companion object {
        const val LIST = "list"
        const val REQUEST_CODE = 134
        fun newInstance(list: ArrayList<String>) = SelectListDialog().apply {
            arguments = bundleOf(LIST to list)
        }
    }
}


5cb360aa5117a851399043.png
  • Вопрос задан
  • 273 просмотра
Решения вопроса 1
zagayevskiy
@zagayevskiy Куратор тега Android
Android developer at Yandex
Не сохраняй этот диалог в поле другого фрагмента, а если сохраняешь - зануляй ссылку на него, когда он уже не нужен.
Что за извращения с onActivityResult? Сделай свой интерфейс, реализуй его в target, и касти к нему, дергай нужный метод. Зачем лишний раз через интент передавать данные, если можно напрямую.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы