我们一般都是在使用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();
}
}