0

I am reading this from Google about using DialogFragment. Everything works until the section Creating a Custom Layout: when the call is done to display a DialogFragment with a custom layout I get a OutOfMemoryError exception.

I have just slighty modified the code from the article, and my app only contains the 3 elements below:

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar)

        fab.setOnClickListener { view ->
            showDialog()
        }
    }


    fun showDialog() {
        // Create an instance of the dialog fragment and show it
        val dialog = FireMissilesDialogFragment()
        dialog.show(supportFragmentManager, "NoticeDialogFragment")
    }

}

FireMissilesDialogFragment.kt

class FireMissilesDialogFragment : DialogFragment() {

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity?.let {
            val builder = AlertDialog.Builder(it)

            // Inflate and set the layout for the dialog
            // Pass null as the parent view because its going in the dialog layout
            builder.setView(layoutInflater.inflate(R.layout.dialog_layout, null))
                // Add action buttons
                .setPositiveButton(R.string.ok) { dialog, id ->
                    Log.d("FireMissiles", "TEST")
                }
                .setNegativeButton(R.string.cancel) { dialog, id ->
                    getDialog().cancel()
                }
            builder.create()
        } ?: throw IllegalStateException("Activity cannot be null")
    }
}

dialog_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content">

    <EditText
            android:id="@+id/username"
            android:inputType="textEmailAddress"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="4dp"
            android:layout_marginRight="4dp"
            android:layout_marginBottom="4dp"
            android:hint="@string/ok" android:importantForAutofill="no"/>
    <EditText
            android:id="@+id/password"
            android:inputType="textPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:layout_marginLeft="4dp"
            android:layout_marginRight="4dp"
            android:layout_marginBottom="16dp"
            android:fontFamily="sans-serif"
            android:hint="@string/cancel" android:importantForAutofill="no"/>
</LinearLayout>

My code has only these 3 elements above. I guess there is somewhere a memory leak but I cannot find it.

Does someone have an idea?


Answers to comments and solution:

@Sam I do not use any image, this project is just a attempt to use DialogFragment, hence it is based on standard empty Activity project with fab, only thing I did not show is the activity_main.xml but it is the standard one.

@Tobias, thanks for the hint but it did not solve the problem :(

@user8159708, thank you!! that solved the problem. My code is now (and it is the only thing I changed):

class FireMissilesDialogFragment : DialogFragment() {

    lateinit var mView: View

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

        setDialog()

        return mView
    }

    fun setDialog(){
        activity?.let {
            val builder = AlertDialog.Builder(it)

            // Inflate and set the layout for the dialog
            // Pass null as the parent view because its going in the dialog layout
            builder.setView(mView)
                // Add action buttons
                .setPositiveButton(R.string.ok) { dialog, id ->
                    Log.d("FireMissiles", "TEST")
                }
                .setNegativeButton(R.string.cancel) { dialog, id ->
                    Log.d("FireMissiles", "TEST")
                    //getDialog().cancel()
                }
            builder.create()
        } ?: throw IllegalStateException("Activity cannot be null")
    }
}
eqtèöck
  • 971
  • 1
  • 13
  • 27
  • Somethings not adding up here. I don't think you have supplied enough information. OutOfMemory typically comes from poor image handling or infinite circular calls of reserving memory. Confirm you are not attempting to launch this in a loop and confirm you are not using any images whatsoever. If you are using images, then what bucket did you put them in and what size are they. – Sam Feb 13 '19 at 15:17

3 Answers3

1

Don't create your dialog using an alert builder.

Remove your override of onCreateDialog.

Inflate your view in onCreateView:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.dialog_layout, container, false)
    }

Add some buttons to your layout yourself, and set your onClickListeners manually after inflating your view.

TomH
  • 2,581
  • 1
  • 15
  • 30
0

This sounds like loop.

Try to remove getDialog().cancel() and just return null instead.

You don't need to explicitely close Dialoges.

Tobias
  • 7,282
  • 6
  • 63
  • 85
0

I think you are doing it wrong. You don't need to use AlertDialog.Builder as you are already extending from DialogFragment.

You can follow this link.

It is in Java, but in Kotlin it will be similar.