Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should an internal DialogFragment class be static or not?

This is a snippet of code from my project that I am using to learn Android:

private void enableLocationSettings() {
    Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
    startActivity(settingsIntent);
}

@SuppressLint("ValidFragment")
public class EnableGpsDialogFragment extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return new AlertDialog.Builder(getActivity())
            .setTitle("Tytuł")
            .setMessage("wiadomosc")
            .setPositiveButton("odpal", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {
                    enableLocationSettings();
                }

            })
            .create();
    }
} 

As you can see I must add @SuppressLint to make my app work but on the guide this annotation wasn't necessary.

What am I doing wrong?

Here are my imports:

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Settings;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.DialogFragment;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
import android.widget.ToggleButton;
like image 798
szpic Avatar asked Mar 14 '13 16:03

szpic


1 Answers

All DialogFragments should be public and - if an inner class - static. They should also have a public no-arg constructor, and rely only on setArguments() for parameter passing.

Failing to comply to this has for some time produced a Lint warning, that you could suppress if you really wanted to, but starting from the Android support library v25 and on, you will actually get an exception if trying to show a DialogFragment that doesn't comply to these rules:

java.lang.IllegalStateException: Fragment TestActivity$TestDialogFrament must be a public static class to be properly recreated from instance state.

The reason is, as stated, that the OS must be able to recreate all fragments in case something like a low-memory situation forces it to destroy fragments when an app is put into the background. When the app is put in the foreground again, the fragments should be possible to re-create from the serialized application state, and that is not possible for non-static inner classes other than from an instance of the enclosing outer class, and the re-creation is not done from that context.

Unfortunately this makes things more complex for dialogs, since it's usually very convenient to just create an anonymous sub-class that overrides onCreateDialog. However, such a dialog would not be able to re-create at all.

like image 180
JHH Avatar answered Nov 03 '22 00:11

JHH