当前位置:网站首页>Android Interviewer: can you stand up to the 12 questions of windows? (help me up, I can still ask)

Android Interviewer: can you stand up to the 12 questions of windows? (help me up, I can still ask)

2021-02-23 17:47:25 Smurf 8091

Preface

interviewer : About Window, How much do you know ?

Let's see if you can answer all the following questions .

If you have these problems

  • Window What is it? ? and View The relationship between ?
  • WindowManager What is it? ? and WMS The relationship between ?
  • How to add a Window?
  • Window How to display to the lock screen interface
  • Window When all three types exist , How is the display hierarchy .
  • Window Is refers to PhoneWindow Do you ?
  • PhoneWindow When was it created ?
  • To achieve drag View What to do ?
  • Window The addition of 、 Delete and update process .
  • Activity、PhoneWindow、DecorView、ViewRootImpl The relationship between ?
  • Window Medium token What is it? , What's the usage? ?
  • Application You can pop it up directly in Dialog Do you ?
  • About event distribution , What happened first DecorView Or first Window Of ?

Window What is it?

window . You can understand it as the whole picture on the phone , All views are through Window The present , such as Activity、dialog It's all attached to Window Upper .Window The only implementation of the class is PhoneWindow, This name is easier to remember , Mobile window .

that Window Where on earth is it ? What we see View yes Window Do you ? Yes or no. .

  • If it's just Window Concept Words , That can be said to be true ,View Namely Window The form of being ,Window Manages the View.

  • If it is Window class Words , That's not really View, The only implementation class PhoneWindow Manage the current interface of View, Including the root layout ——DecorView, And the others view And so on .

I don't know if you fainted , Let me summarize ,Window It's a conceptual thing , You can't see him , If you can sense it , So it's through View, therefore View yes Window The form of being , With View, It's only then that you feel View The outer layer has a Emperor's new clothes ——window.

WindowManager What is it? ? and WMS The relationship between ?

WindowManager It's for management Window Of , The implementation class for WindowManagerImpl, The actual work will be entrusted to WindowManagerGlobal Complete in class .

Specific Window operation ,WM Will pass Binder tell WMS,WMS Do the last real operation Window The job of , For this Window Distribute Surface, And draw it on the screen .

How to add a Window?

    var windowParams: WindowManager.LayoutParams = WindowManager.LayoutParams()
    windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
    windowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
    var btn = Button(this)
    windowManager.addView(btn, windowParams)

Simply pasted the code , Added a Button.

Some friends may be confused , This is clearly a Button, It's a View ah , Why Window?

Just said ,View yes Window Form of expression , In practice , add to window It's actually adding something you can't see window, And it has View To make you feel like this is a Window.

So pass windowManager Added View In fact, it is to add Window The process of .

There are two more important attributes :flags and type, I'll talk about it in turn .

Window How to display to the lock screen interface

Window Of flag Can be controlled Window The display characteristics of , That's how to show 、touch Event handling 、 The relationship with equipment 、 wait . So the lock screen display is one of them Flag.

// Window There's no need to get the focus , It doesn't accept all kinds of input events .
public static final int FLAG_NOT_FOCUSABLE = 0x00000008;

// @deprecated Use {@link android.R.attr#showWhenLocked} or
// {@link android.app.Activity#setShowWhenLocked(boolean)} instead to prevent an
// unintentional double life-cycle event.


//  The window can be in the lock screen  Window  Show above 
public static final int FLAG_SHOW_WHEN_LOCKED = 0x00080000;

Window When all three types exist , How is the display hierarchy .

Type Express Window The type of , There are three kinds of :

  • application Window. Corresponding to a Activity,Window The hierarchy is 1~99, At the bottom of the view .
  • Son Window. Cannot exist alone , Need to be attached to a particular parent Window In ( Such as Dialog It's the son Window),Window The hierarchy is 1000~1999.
  • System Window. You need to declare permissions to create Window, such as Toast And system status bar ,Window The hierarchy is 2000-2999, At the top of the view .

You can see , The difference is that there's a Window Hierarchy (z-ordered), The higher level can cover the lower level , Closer to the user .

Window Is refers to PhoneWindow Do you ?

If someone asks me this question , I'm sure I'm going to have a big doubt .

It's not PhoneWindow Do you ? It's the only implementation class , Ask some strange questions .

But I always have to answer this kind of question in the interview ? It's time to pull out Window The concept of .

  • If you mean Window class , that PhoneWindow As the only implementation class , Generally speaking, it means PhoneWindow.

  • If you mean Window The concept , That certainly doesn't mean PhoneWindow, It's real on the interface View. Not all of them, of course View All are Window, But through WindowManager Added to the screen view It's just Window, therefore PopupWindow yes Window, Single... Added to the above question View It's also Window.

PhoneWindow When was it created ?

be familiar with Activity Friends who start the process should know , The startup process goes to ActivityThread Of handleLaunchActivity Method , It's initialized here WindowManagerGlobal, That is to say WindowManager Actual operation Window Class , I'll see later :

 public Activity handleLaunchActivity(ActivityClientRecord r,
                                         PendingTransactionActions pendingActions, Intent customIntent) {
        //...
        WindowManagerGlobal.initialize();
        //...
        final Activity a = performLaunchActivity(r, customIntent);
        //...
        return a;
    }

And then it will go to performLaunchActivity Created in Activity, And call attach Method to initialize some data ( Pseudo code ):

    final void attach() {
        // initialization PhoneWindow
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(mWindowControllerCallback);
        mWindow.setCallback(this);

        // and WindowManager relation 
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

        mWindowManager = mWindow.getWindowManager();
}

You can see , stay Activity Of attach In the method , Created PhoneWindow, And set up callback,windowManager.

there callback I'll talk about it later , It has something to do with event distribution , It can be said that at present Activity and PhoneWindow Make connections .

To achieve drag View What to do ?

I'll go on with what I just did btn Example , If you want to modify btn The location of , Use updateViewLayout that will do , And then in ontouch Method to pass in the moving coordinates .

        btn.setOnTouchListener { v, event ->
            val index = event.findPointerIndex(0)
            when (event.action) {
                ACTION_MOVE -> {
                    windowParams.x = event.getRawX(index).toInt()
                    windowParams.y = event.getRawY(index).toInt()
                    windowManager.updateViewLayout(btn, windowParams)
                }
                else -> {
                }
            }
            false

        }

Window The addition of 、 Delete and update process .

Window All operations are passed WindowManager To complete , and WindowManager It's an interface , His implementation class is WindowManagerImpl, And give it all to WindowManagerGlobal To deal with it . Let's talk about it in detail addView,updateViewLayout, and removeView.

1)addView

//WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {

        if (parentWindow != null) {
            parentWindow.adjustLayoutParamsForSubWindow(wparams);
        }
            
            ViewRootImpl root;
            View panelParentView = null;

            root = new ViewRootImpl(view.getContext(), display);
            view.setLayoutParams(wparams);

            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);

            try {
                root.setView(view, wparams, panelParentView);
            } 
        }
    }
  • Here you can see , Created a ViewRootImpl example , So that means that every Window All correspond to a ViewRootImpl.
  • And then through add Method modified WindowManagerGlobal Some parameters in , such as mViews— Stored all the Window The corresponding View,mRoots—— all Window The corresponding ViewRootImpl,mParams— all Window Corresponding layout parameters .
  • Finally called. ViewRootImpl Of setView Method , Keep looking. .
final IWindowSession mWindowSession;

mWindowSession = WindowManagerGlobal.getWindowSession();

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    //
    requestLayout();

    res = mWindowSession.addToDisplay(mWindow,);
}

setView The method mainly accomplishes two things , One is to pass. requestLayout Method to complete the request of refreshing the interface asynchronously , complete view Drawing process . secondly , Will pass IWindowSession Do it once. IPC call , Give it to WMS To achieve Window The addition of .

among mWindowSession It's a Binder object , Equivalent to a proxy class on the client side , The implementation of the corresponding server is Session, and Session Is running on SystemServer In progress , Specifically, it is in the WMS In service , Finally, it will call this Session Of addToDisplay Method , You can guess from the name of the method that this method is to add Window The logic to the screen , I won't go into the details , Next time we talk about screen drawing, let's talk about it .

2)updateViewLayout

 public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
//...
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;

        view.setLayoutParams(wparams);

        synchronized (mLock) {
            int index = findViewLocked(view, true);
            ViewRootImpl root = mRoots.get(index);
            mParams.remove(index);
            mParams.add(index, wparams);
            root.setLayoutParams(wparams, false);
        }
    }

Here's an update WindowManager.LayoutParams and ViewRootImpl.LayoutParams, And then in ViewRootImpl Inside, too, there will be a new focus on View Drawing , Finally through IPC signal communication , Call to WMS Of relayoutWindow Update complete .

3)removeView

public void removeView(View view, boolean immediate) {
        if (view == null) {
            throw new IllegalArgumentException("view must not be null");
        }

        synchronized (mLock) {
            int index = findViewLocked(view, true);
            View curView = mRoots.get(index).getView();
            removeViewLocked(index, immediate);
            if (curView == view) {
                return;
            }

            throw new IllegalStateException("Calling with view " + view
                    + " but the ViewAncestor is attached to " + curView);
        }
    }
    
    
    private void removeViewLocked(int index, boolean immediate) {
        ViewRootImpl root = mRoots.get(index);
        View view = root.getView();

        if (view != null) {
            InputMethodManager imm = view.getContext().getSystemService(InputMethodManager.class);
            if (imm != null) {
                imm.windowDismissed(mViews.get(index).getWindowToken());
            }
        }
        boolean deferred = root.die(immediate);
        if (view != null) {
            view.assignParent(null);
            if (deferred) {
                mDyingViews.add(view);
            }
        }
    }

In this method , adopt view find mRoots The corresponding index in , And then the same goes to ViewRootImpl In the middle of View Delete work , adopt die Method , Finally, it comes to dispatchDetachedFromWindow() In the method , I mainly did the following things :

  • Callback onDetachedFromeWindow.
  • Garbage collection related operations ;
  • adopt Session Of remove() stay WMS Delete in Window;
  • adopt Choreographer Remove the monitor

Activity、PhoneWindow、DecorView、ViewRootImpl The relationship between ?

After watching the above process , Let's deal with the relationship between these four little partners :

  • PhoneWindow  It's actually Window The only subclass of , yes  Activity  and View The middle layer of interactive system , Used to manage View Of , And in Window establish ( add to ) It's new when it's new ViewRootImpl example .
  • DecorView  As a whole View Top of hierarchy ,ViewRootImpl yes DecorView Of parent, But he's not a real View, Just inherited ViewParent Interface , To be in charge of View Of various events , Include requestLayout、invalidate、dispatchInputEvent wait .

Window Medium token What is it? , What's the usage? ?

token? What is it again ? Just now, window It didn't appear during the operation .

token In fact, we should find a trace in our work , such as application To create dialog When , You're going to report a mistake :

unable to add window --token null

So this token Follow window The operation is relevant , Turn to just now addview In the method , There's another detail we haven't talked about , Namely adjustLayoutParamsForSubWindow Method .

//Window.java
    void adjustLayoutParamsForSubWindow(WindowManager.LayoutParams wp) {
        if (wp.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&
                wp.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {
            // Son Window
            if (wp.token == null) {
                View decor = peekDecorView();
                if (decor != null) {
                    wp.token = decor.getWindowToken();
                }
            }
        } else if (wp.type >= WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW &&
                wp.type <= WindowManager.LayoutParams.LAST_SYSTEM_WINDOW) {
            // System Window
        } else {
            // application Window
            if (wp.token == null) {
                wp.token = mContainer == null ? mAppToken : mContainer.mAppToken;
            }
            
        }
    }

The above codes represent three different types Window The type of :

  • Son Window. Need from decorview Get in the token.
  • System Window. Unwanted token.
  • application Window. Take it directly mAppToken,mAppToken Is in setWindowManager From the method , That's new Window I brought it in when I was young token.

And then in WMS Medium addWindow Method will verify this token, Next time we talk about WMS I'll take a look at it later .

So this token It's used to verify whether you can add Window, It can be understood as permission verification , In fact, it's just to prevent developers from abusing context establish window.

Have token Of context( such as Activity) You can operate Window. No, token The context of ( such as Application) It's not allowed to add Window To screen ( Besides the system Window).

Application You can pop it up directly in Dialog Do you ?

This question is actually related to the above question :

  • If used directly Application The context of cannot be created Window Of , and Dialog Of Window The grade belongs to the child Window, Must be attached to other fathers Window, So you have to pass in Activity This kind of window The context of .
  • Is there any other way to Application Pop up in dialog Well ? Yes , Change to system level Window:
// Check authority 
if (!Settings.canDrawOverlays(this)) {
    val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
    intent.data = Uri.parse("package:$packageName")
    startActivityForResult(intent, 0)
}

dialog.window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG)

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  • There's another way , stay Application Class , Can pass registerActivityLifecycleCallbacks monitor Activity Life cycle , But this method is also introduced Activity Of context, But in Application Class .

About event distribution , What happened first DecorView Or first Window Of ?

After a series of problems mentioned above , If it's Window I'm more impressed ? Finally, one more question , This is wanandroid What I saw on the Forum ,

there window It can be understood as PhoneWindow, In fact, this question is about the distribution of events in Activity、DecorView、PhoneWindow Order in .

When the screen is touched , First, the touch event will be generated by the hardware and sent to the kernel , Then walk to FrameWork layer ( Specific process interested can see the reference link ), Finally, after a series of event processing, we arrive at ViewRootImpl Of processPointerEvent Method , Next is what we're going to analyze :

//ViewRootImpl.java
 private int processPointerEvent(QueuedInputEvent q) {
            final MotionEvent event = (MotionEvent)q.mEvent;
            ...
            //mView distribution Touch event ,mView Namely DecorView
            boolean handled = mView.dispatchPointerEvent(event);
            ...
        }

//DecorView.java
    public final boolean dispatchPointerEvent(MotionEvent event) {
        if (event.isTouchEvent()) {
            // distribution Touch event 
            return dispatchTouchEvent(event);
        } else {
            return dispatchGenericMotionEvent(event);
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        //cb In fact, it's the corresponding Activity
        final Window.Callback cb = mWindow.getCallback();
        return cb != null && !mWindow.isDestroyed() && mFeatureId < 0
                ? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);
    }


//Activity.java
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

//PhoneWindow.java
    @Override
    public boolean superDispatchTouchEvent(MotionEvent event) {
        return mDecor.superDispatchTouchEvent(event);
    }

//DecorView.java
    public boolean superDispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }

The distribution process of events is clear :

ViewRootImpl——>DecorView——>Activity——>PhoneWindow——>DecorView——>ViewGroup

( And that's where getCallback Parameters , That's before addView In the middle of callback, That is to say Activity In itself )

But the process is a bit strange , Why do you go around , light DecorView Just walked twice .

I agree with the statement in the link , The main reason is decoupling .

  • ViewRootImpl I didn't know there was Activity This kind of thing exists , It just holds DecorView. So I passed it on to DecorView, and DecorView Know there are AC, So it was passed on to AC.
  • Activity I don't know DecorView, It just holds PhoneWindow, So this call chain is formed .

Interview review route

Don't say anything superfluous , Next, I will share a review route for the interview , But if you don't know how to prepare for the interview efficiently , You can refer to my review route , You are welcome to communicate with each other if you have any questions , Come on! !

Here's a direction for you , Learn systematically :

1、 Watch the video for systematic learning

Last few years Crud experience , Let me understand that I'm really a fighter in the chicken , And because Crud, Lead to their own technology more fragmented , It's not deep enough, it's not systematic enough , So it is necessary to study again . What I need is system knowledge , Poor structural framework and ideas , So learn through video , better , And more comprehensive . About video learning , Individuals can recommend B Stand for learning ,B There are a lot of learning videos on the station , The only drawback is that it's free and it's easy to get out of date .

in addition , I've collected several videos myself , I can share with you what I need .

2、 Systematically sort out the knowledge , Raise reserves

There are so many knowledge points in client development , There are still so many things to ask about in the interview . So there's no other trick to an interview , It depends on how well you are prepared for these knowledge points .so, When you go out for an interview, you should first see which stage you have reviewed .

System learning direction :

  • The necessary skills for an architect to build a foundation : thorough Java Generic + The notes are simple + Concurrent programming + Data transmission and serialization +Java Principle of virtual machine + Reflection and class loading + A dynamic proxy + Efficient IO

  • Android senior UI And FrameWork Source code : senior UI promotion +Framework Kernel parsing +Android Component kernel + Data persistence

  • 360° Comprehensive performance tuning : Design ideas and code quality optimization + Program performance optimization + Development efficiency optimization

  • Interpretation of open source framework design ideas : Thermal repair design + Plug in framework interpretation + Component frame design + Image loading framework + Network access framework design +RXJava Responsive programming framework design +IOC Architecture design +Android Architecture components Jetpack

  • NDK Module development : NDK Basic knowledge system + Bottom image processing + Audio and video development

  • Wechat applet : Introduction to applet +UI Development +API operation + Wechat docking

  • Hybrid Development and Flutter: Html5 Project practice +Flutter Advanced

After sorting out the knowledge , We need to make up for it , So for these knowledge points , I also have a lot of e-books and notes on hand , These notes make a perfect summary of each knowledge point .

3、 Read source code , Look at the actual combat notes , Learn the idea of the great God

“ Programming language is the way programmers express themselves , And architecture is the programmer's perception of the world ”. therefore , Programmers want to quickly recognize and learn Architecture , Reading the source code is essential . Read the source code , It's about solving problems + Understand things , More important, : See the idea behind the source code ; The programmer said : Read Wanxing source code , Practice in thousands of ways .

It mainly contains wechat MMKV Source code 、AsyncTask Source code 、Volley Source code 、Retrofit Source code 、OkHttp Source code and so on .

4、 Before the interview , Brush the topic, sprint

Within the week before the interview , You can start to brush questions and sprint . please remember , When I brush the questions , Technology first , Look at the basic algorithm , Such as sorting , And intelligence questions , Except for school recruitment , Otherwise, I don't usually ask .

About the interview questions , I have also prepared a set of systematic interview questions , Help you draw inferences from one instance :

These contents are shared for free , Need a full version of friends , Click here to see the whole thing

版权声明
本文为[Smurf 8091]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/02/20210223174446214E.html

随机推荐