DialogFragment is better than Dialog in Android

First of all, DialogFragment was launched by Google along with Fragment. DialogFragment is based on Fragment, and its life cycle is the same as Fragment.

In Android, there are several ways to implement dialogs:

  1. Dialogue/Age
  2. DialogFragment
  3. Activity's Style is set to Dialog

Usually, we realize the effect of dialog by inheriting Dialog in development, but the life cycle of dialog-based dialog will not follow Activity, we can write a simple code to see:

public class MyDialogActivity extends AppCompatActivity {
    private static final String TAG = "MyDialogActivity";
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        Log.e(TAG,"onCreate");
        setContentView(R.layout.activity_dialog);

        Button button = findViewById(R.id.button4);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MyDialog myDialog = new MyDialog(MyDialogActivity.this);
                myDialog.show();

            }
        });
        / / Delay 2 seconds to actively close the Activity
        Handler handler = new Handler ();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        },2000);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.e(TAG,"onResume");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.e(TAG,"onStart");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.e(TAG,"onRestart");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.e(TAG,"onPause");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy ();
        Log.e(TAG,"onDestroy");
    }
    @Override
    protected void onStop() {
        super.onStop();
        Log.e(TAG,"onStop");
    }

    static class MyDialog extends Dialog {
        private String TAG = "Dialog";
        public MyDialog(@NonNull Context context) {
            super(context);
            setContentView(R.layout.dialog_demo);
        }

        @Override
        protected void onStop() {
            super.onStop();
            Log.e(TAG,"onStop");
        }

        @Override
        protected void onStart() {
            super.onStart();
            Log.e(TAG,"onStart");
        }

        @Override
        public void cancel() {
            super.cancel();
            Log.e(TAG,"cancel");
        }

        @Override
        public void dismiss() {
            super.dismiss();
            Log.e(TAG,"dismiss");
        }

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate (savedInstanceState);
            Log.e(TAG,"onCreate");
        }


    }

}

After running, open a Dialog, and then close the Dialog with a delay of two seconds, and found that an error was reported in the Log:


Roughly speaking, the Dialog was not closed, causing a memory leak

The solution is also very simple, actively close in the onDestory method in the Activity:

@Override
    protected void onDestroy() {
        super.onDestroy ();
        if (myDialog != null){
            myDialog.cancel();
        }
        Log.e(TAG,"onDestroy");
    }

If you have to do this every time, it feels cumbersome, why can't the system be recycled by itself? Here you can use DialogFragment:

public class MyDialogFragment extends DialogFragment {
    private static final String TAG = "MyDialogFragment";

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        Log.d(TAG,"onCreate");
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        Log.d(TAG,"onCreateView");
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Log.d(TAG,"onDetach");
    }

    @Override
    public void onDestroy() {
        super.onDestroy ();
        Log.d(TAG,"onDestroy");
    }
}

From the log, when the life cycle of Activity changes, the life cycle of DialogFragment also changes, which is the same as Fragment, so it can be ensured that the life cycle of the dialog box is consistent with the life cycle of Activity to avoid memory leaks

By the way, when you click to pop up a dialog box, do not directly create a new dialog box. If it can be reused, try to reuse it as much as possible to reduce the creation of objects.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325775328&siteId=291194637