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

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

Похожие вопросы