Android中DialogFragment优于Dialog

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

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

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

  1. Dialog/Alter
  2. DialogFragment
  3. 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中竟然报错了:


大致的意思,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");
    }
}

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

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

目录
相关文章
|
7月前
|
XML Android开发 数据格式
Android面试题之DialogFragment中隐藏导航栏
在Android中展示全屏`DialogFragment`并隐藏状态栏和导航栏,可通过设置系统UI标志实现。 记得在布局文件中添加内容,并使用`show()`方法显示`DialogFragment`。
89 2
|
Android开发
关于安卓DialogFragment使用(三)
关于安卓DialogFragment使用(三)
327 0
|
Android开发
Android DialogFragment 的封装
Android DialogFragment 的封装
|
Android开发
关于安卓底部dialogfragment封装
关于安卓底部dialogfragment封装
403 0
|
Android开发
关于安卓DialogFragment基类封装
安卓DialogFragment基类封装
192 0
|
Android开发 容器 数据格式
Android DialogFragment使用
1. 简单使用 继承DialogFragment /** * 显示系统的对话框Fragment * @author mazaiting * @date 2018/3/1 */ public class CustomDialogFragm...
1127 0
|
Android开发 容器
Android开发 - 解决DialogFragment在全屏时View被状态栏遮住的问题
我的上一篇文章:设置DialogFragment全屏显示 可以设置对话框的内容全屏显示,但是存在在某些机型上顶部的View被状态栏遮住的问题。经过测试,发现了一种解决办法,在DialogFragment的onCreateView()中添加一个布局监听器: @Override public View.
2501 0
|
Android开发 uml 容器
Android基于DialogFragment封装一个通用的Dialog
1、内置Dialog常用默认的样式,内置样式可自行修改 2、支持自定义复杂的布局、动画、对话框大小、背景色等设 3、统一管理多个dialog并顺序弹出
6158 0

热门文章

最新文章

  • 1
    如何修复 Android 和 Windows 不支持视频编解码器的问题?
  • 2
    Android历史版本与APK文件结构
  • 3
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 4
    【04】flutter补打包流程的签名过程-APP安卓调试配置-结构化项目目录-完善注册相关页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程
  • 5
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
  • 6
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
  • 8
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
  • 9
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 10
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 1
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    24
  • 2
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    32
  • 3
    Android历史版本与APK文件结构
    120
  • 4
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    27
  • 5
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    23
  • 6
    APP-国内主流安卓商店-应用市场-鸿蒙商店上架之必备前提·全国公安安全信息评估报告如何申请-需要安全评估报告的资料是哪些-优雅草卓伊凡全程操作
    56
  • 7
    【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    37
  • 8
    当flutter react native 等混开框架-并且用vscode-idea等编译器无法打包apk,打包安卓不成功怎么办-直接用android studio如何打包安卓apk -重要-优雅草卓伊凡
    73
  • 9
    【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
    118
  • 10
    Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
    29