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:
- Dialogue/Age
- DialogFragment
- 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.