Why Dialog can only use the Context of Activity

A Dialog has gone through the following steps from scratch

  • First, a new Window is created, the type is PhoneWindow, which is similar to the process of creating a Window by Activity, and a setCallbackcallback is set  .

  • Associate this new Window with the WindowManagerobject obtained from the Activity  , that is, the dialog and the Activity share the same  WindowManagerobject.

  • The show method shows the Dialog, and first calls back the Dialog  onCreate,onStartmethod.

  • Then get the Dialog's own  DecorViewobject, and add it to the WindowManager object through the addView method, and the Dialog appears on the screen.

Analyzing this process, we can also learn some small problems that we usually encounter, such as why Dialog must be attached to the Activity display? Because Activity needs to be used during the Dialog creation process Context, that is , it needs tokento be created using Activity window. So the content passed into Application will report an error- "Unable to add window - token null is not for an application" .

Back to the topic, this process is summarized in one sentence , Dialog uses the WindowManager object of Activity, and adds a new Window on top of it DecorView.

Context must be Activity

Obtaining windowManager in dialog

mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);

If the above context is Application, ContextImpl.getSystemService is actually called, and the obtained WM is new WindowManagerImpl(display), that is, mParentWindow is null;
if the above context is Activity, the obtained WM is new WindowManagerImpl(mDisplay, parentWindow), and this parentWindow is PhoneWindow in Activity, and mAppToken is set for this PhoneWindow.

When the dialog is created, if the incoming constructor is not an activity type context, the variable mParentWindow of the WindowManagerImpl type of Window will be null, which will cause the addView of WindowManagerGlobal to not call the adjustLayoutParamsForSubWindow method of Window, thus not assigning a value to attr.token , Causing the authentication in the WindowManagerService service to fail, and a BadTokenException exception is thrown.

You can see that only the parentWindow is not empty will go to the adjustLayoutParamsForSubWindow method,

The token is saved in the adjustLayoutParamsForSubWindow method. Only the correct token can complete the information verification in the subsequent cross-process communication process.

The literal translation of Token into Chinese is the meaning of token. Android system uses it as a security mechanism. Its essence is a Binder object, which acts as a verification code in cross-process traffic. For example: the activity startup process and interface drawing process will involve the communication between ActivityManagerService, application, WindowManagerService three processes, at this time Token acts as an authentication function in these three processes, ActivityManagerService and WindowManagerService through the application The Token passed by the activity of the program to distinguish which activity is controlling the application.

reference:

https://www.jianshu.com/p/3a1b40f4de36

https://www.jianshu.com/p/413ec659500a

Guess you like

Origin blog.csdn.net/cpcpcp123/article/details/115185759