Android中Dialog源码解析

我们一般都是在使用AlertDialog,但AlertDialog主要也是继承自Dialog。下面我们来分析分析Dialog源码。

一、Dialog构造函数

public Dialog(Context context) {
    this(context, 0);
}

public Dialog(Context context, int theme) {
    //创建一个Context
    mContext = new ContextThemeWrapper(
        context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);
    //获取一个WindowManager对象
    mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
    //创建一个Window对象
    Window w = PolicyManager.makeNewWindow(mContext);
    //将Window对象w赋值给mWindow
    mWindow = w;
    //为Windowd对象设置回调,并且它本身实现了这些回调函数
    w.setCallback(this);
    //为Window对象设置WindowManager对象
    w.setWindowManager(mWindowManager, null, null);
    w.setGravity(Gravity.CENTER);
    //得到当前线程
    mUiThread = Thread.currentThread();
    //创建一个对话框监听Handler
    mListenersHandler = new ListenersHandler(this);
}

从上面我们可以看到Dialog的创建过程其实跟Activity类似,它本质也是一个Window。所以的很多地方跟Activity相似。

二、Dialog生命周期

/**
 * 类似于Activity的onCreate函数,可以在这个方法中进行Dialog的一些初始化操作
 * 包括调用setContentView方法
 */
protected void onCreate(Bundle savedInstanceState) {
}

/**
 * 当对话框启动的时候被调用.
 */
protected void onStart() {
}

/**
 * 当对话框停止的时候被调用.
 */
protected void onStop() {
}

三、对话框的显示

public void show() {
    //首先判断对话框是否显示
    if (mShowing) {
        if (mDecor != null) {
            mDecor.setVisibility(View.VISIBLE);
        }
        return;
    }
    /*判断对话框是否创建过,如果没有创建过
    * 在dispatchOnCreate里面就会回调onCreate函数
    */
    if (!mCreated) {
        dispatchOnCreate(null);
    }
    //回调onStart函数
    onStart();
    //获取Window对象总的DecorView,如果调用了setContentView就会创建DecorView
    mDecor = mWindow.getDecorView();
    //下面就会获取布局的一些属性
    WindowManager.LayoutParams l = mWindow.getAttributes();
    if ((l.softInputMode
            & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
        WindowManager.LayoutParams nl = new WindowManager.LayoutParams();
        nl.copyFrom(l);
        nl.softInputMode |=
                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
        l = nl;
    }

    try {
        //将DecorView添加到WindowManager中,这些就会显示了
        mWindowManager.addView(mDecor, l);
        mShowing = true;

        sendShowMessage();
    } finally {
    }
}

从上面可以看到它是将Window中的DecorView添加到了WindowManager中来进行显示的。

四、Dialog的销毁

public void dismiss() {
    /*判断当前线程释放为UI线程
    *如果不是UI线程,则将mDismissAction到UI线程中执行
    *如果是UI线程,则直接执行mDismissAction的run方法
    *也就是销毁操作在mDismissAction的run方法中
    */
    if (Thread.currentThread() != mUiThread) {
        mHandler.post(mDismissAction);
    } else {
        mDismissAction.run();
    }
}

下面我们来看看mDismissAction对象的类:

private final Runnable mDismissAction = new Runnable() {
    public void run() {
        dismissDialog();
    }
};  

private void dismissDialog() {
    //首先判断Decor是否存在以及是否显示
    if (mDecor == null || !mShowing) {
        return;
    }
    //将DecorView从WindowManger对象中移除
    try {
        mWindowManager.removeView(mDecor);
    } finally {
        mDecor = null;
        mWindow.closeAllPanels();
        //回调onStop方法
        onStop();
        mShowing = false;

        sendDismissMessage();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值