Android中DialogFragment优于Dialog?

作者: helang1991 | 来源:发表于2018-07-26 16:41 被阅读347次

    首先DialogFragment是跟随Fragment一起被Google推出的,DialogFragment是基于Fragment的,生命周期和Fragment是一样的。

    在Android中,实现对话框的方式多种:

    Dialog/Alter

    DialogFragment

    Activity的Style设置成Dialog

    通常,我们在开发中实现通过继承Dialog来实现对话框的效果,但是,基于Dialog的对话框生命周期是不会随着Activity的,我们可以写一段简单的代码来看看:

     
    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();
     
                }
            });
            //延时2秒主动关闭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");
            }
     
     
        }
     
    }
    
    

    运行起来后,打开一个Dialog,然后延时两秒关闭Dialog,发现Log中竟然报错了:

    image

    大致的意思,Dialog没被关闭,造成了内存泄漏

    解决办法也很简单,在Activity中的onDestory方法中主动关闭:

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

    如果每次都要这样做,感觉比较繁琐,为什么不能让系统自己来回收呢?这里就可以使用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");
        }
    }
    
    
    image

    从日志来看,当Activity生命周期发生变化的时候,DialogFragment的生命周期也在发生变化,这和Fragment是一样的,因此可以保证当对话框的生命周期和Activity的生命周期保持一致,避免内存泄漏

    顺便提一下,在通过点击弹出对话框的时候,不要直接new一个对话框,如果可以复用,就尽量复用,减少对象的创建

    相关文章

      网友评论

        本文标题:Android中DialogFragment优于Dialog?

        本文链接:https://www.haomeiwen.com/subject/aoibmftx.html