Understanding Dialog in Android

Time:2022-11-14

PS: This article is a reprinted article, the readability of the original text will be better, and there is a link to the original text at the end of the article

PS: This article is based on Android Api 26 to analyze the source code. 1. Where is Dialog’s Window created? Where is Dialog’s Window created? Let’s take a look at a constructor of Dialog, which is the Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper) method;
Understanding Dialog in Android
Seeing that the code in Note 1 is not, it creates a Window, and the implementation class of this Window is PhoneWindow, which, like Activity, also uses PhoneWindow as its own Window; well, since there is a Window, there must be a View displayed. right? Then let’s see how the PhoneWindow of this Dialog loads the View, let’s take a look at one of the Dialog’s methods of loading the View, setContentView(@LayoutRes int layoutResID);
Understanding Dialog in Android
mWindow is Window, and the implementation class of Window is PhoneWindow, so let’s look down at the setContentView(@LayoutRes int layoutResID) method of PhoneWindow;
Understanding Dialog in Android
Seeing that PhoneWindow’s setContentView(@LayoutRes int layoutResID) method does not, the Activity’s setContentView(@LayoutRes int layoutResID) method resolves the View process and the Dialog’s setContentView(@LayoutRes int layoutResID) method resolves the View process is the same, so it is not necessary for PhoneWindow. The setContentView(@LayoutRes int layoutResID) method is analyzed, you can see this article to understand it by analyzing the setContentView method of AppCompatActivity in Android. 2. Do we encounter such a problem when we usually develop: If the Context used by Dialog is not Activity but Application, then an error will be reported. Well, for a better understanding, let’s start with a simple code;
Understanding Dialog in Android
Run the app and find the following error:
Understanding Dialog in Android
The reason for the error here is that there is no application token. The application token is generally only owned by the Activity, so here only the Context of the Activity is used as the Dialog; here because the token of the Application is empty, and the Dialog is created at the beginning When Winow, the token must be empty; let’s take a look at a construction method of Dialog, that is Dialog(@NonNull Context context, @StyleRes int themeResId, boolean createContextThemeWrapper);
Understanding Dialog in Android
Looking at the code in Note 3, if the second parameter is null, it means that the token of the Dialog is null; the window type of the Dialog is of type TYPE_APPLICATION, and it is required to be the Token of the Activity, otherwise the system will throw a BadTokenException exception; Dialog It is the application window type, and the Token must be the Token of the Activity; let’s take a look at the code in Note 2, assuming that the context is an Activity, and see that the getSystemService method is passed in Context.WINDOW_SERVICE, OK, let’s take a look at the Activity’s getSystemService method;
Understanding Dialog in Android
Looking at the code in Note 4, nam is Context.WINDOW_SERVICE, so mWindowManager is returned, and the implementation class of mWindowManager is WindowManagerImpl; when does Activity set the token? The answer is in the Activity’s attach method;
Understanding Dialog in Android
See the code in Note 5, the second parameter is the token of the Activity, well, let’s look down at the setWindowManager method of Window;
Understanding Dialog in Android
The code in Note 6 just saves the token to the Window of the Activity; see the code in Note 7, where this refers to the PhoneWindow of the Activity; well, let’s look down at the createLocalWindowManager method of WindowManagerImpl;
Understanding Dialog in Android
The createLocalWindowManager method of WindowManagerImpl calls the WindowManagerImpl(Context context, Window parentWindow) method;
Understanding Dialog in Android
What is mParentWindow? When you look at the name, you know that it must be the parent Window of a certain Window, that is to say, the Activity’s Window is the parent Window of a certain Window; when will the Activity’s token be given to the Dialog? Let’s take a look at the show method of Dialog;
Understanding Dialog in Android
The comment 9 code is actually the View process of displaying the Dialog, and mShowing is set to true, indicating that the View is being displayed; well, let’s look at the implementation of the comment 9 code, mWindowManager is WindowManagerImpl, let’s look at addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) method;
Understanding Dialog in Android
The mParentWindow in Note 10 is the PhoneWindow of the Activity (if mContext is the Activity), and mGlobal is the WindowManagerGlobal. Let’s take a look at the addView(View view, ViewGroup.LayoutParams params, Display display, Window parent-Window) method of WindowManagerGlobal;
Understanding Dialog in Android
Looking at the code in Note 11, the parentWindow is the PhoneWindow of the Activity, so the adjustLayoutParamsForSubWindow(WindowMana-ger.LayoutParams wp) method of the Window is executed;
Understanding Dialog in Android
See the code in Note 12, the decor is essentially the DecorView of the PhoneWindow in the Activity, the decor gets mAttachInfo.mWindowToken, and mAttachInfo.mWindowToken is the token of the PhoneWindow in the Activity, so the show process in the Dialog actually also displays the Activity’s token is assigned to Dialog. Didn’t we mentioned above that Dialog’s Window is a TYPE_APPLICATION type of window? How to prove it is? Well, let’s go back and look at the code of comment 8, which is the getAttributes method of PhoneWindow of Dialog, which is implemented in Window;
Understanding Dialog in Android
What is mWindowAttributes, let’s look at the declaration of mWindowAttributes;
Understanding Dialog in Android
Let’s take a look at the parameterless constructor of WindowManager.LayoutParams;
Understanding Dialog in Android
See the code in Note 13, the default type of Window is TYPE_APPLICATION, and the Dialog’s Window does not change the type, so the Dialog’s Window is a TYPE_APPLICATION type of window. Finally, let’s take a look at the implementation of Dialog’s dismiss method;
Understanding Dialog in Android
See note 14, if the current thread is the main thread, then execute the dismissDialog method directly; see note 15, if it is not the main thread, then switch to the main thread to execute; well, let’s continue to look at the dismissDialog method of Dialog;
Understanding Dialog in Android
Look at the code in comment 16, and finally remove the DecorView from the PhoneWindow and it’s done.