日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

源码阅读分析 - Window底层原理与系统架构

發布時間:2023/12/20 windows 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 源码阅读分析 - Window底层原理与系统架构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

做了一段的時間的 android 我們就開始聽到有人說 AMS、WMS、Window、WindowManager、WindowManagerService等等這些詞匯,可能了解但是腦海里未必有架構圖, 這次我們就從源碼的角度來了解一下。在閱讀本文之前希望你可以花點時間了解下面幾篇文章:

1. 插件式換膚框架搭建 - setContentView源碼閱讀
2. Android進程間的通信 - IPC(機制)Binder的原理和源碼閱讀
2. Android插件化架構 - Activity的啟動流程分析
3. 源碼解析 - View的繪制流程

如何閱讀源碼

上面幾篇文章和我今天的這篇文章有著千絲萬縷的聯系,我為什么可以把他們分開來?有很重要的一點,我們是需要用到才會去看源碼,打個比方我想做一個皮膚切換的功能,那么我肯定需要去了解布局資源的加載過程,而這個你僅僅從網上看看別人寫好的文章或者 copy 幾行代碼相信你應該很難做到,當然去 github 上面選個 demo 用用也行,但你心里不覺得少了點什么嗎?還有我們最好能夠點到即止,帶著疑問,只需要清楚我們想要了解什么,今天的很多源碼或多或少都會涉及到上面幾篇文章的知識點但我們不用管。相信我,只要你能夠多對著別人的文章自己打開源碼看看,隨著時間的推移當我們再看系統源碼的時候就會得心應手,解決問題再也不是靠蒙和試(如果你在開發過程中有時候靠蒙可以在文章末尾刷個贊),而且如果心中有整個 android 應用層的源碼架構圖,對于開發和解決問題方面屢試不爽(如果你能看懂 native 層的源碼更好)。

我們的疑問

我們只是知道 setContentView 方法可以設置顯示我們的布局,這篇 插件式換膚框架搭建 - setContentView源碼閱讀 文章只是帶大家了解了布局的層次結構,但你了解 Window 和 WindowManager 都干了些什么嗎?又或者當我們觸摸一個 EditText 的時候會彈出一個系統的鍵盤,為什么彈出鍵盤我們的 Activity 布局會自動做調整?我們彈一個 Toast 但就算我們退出 Activity 或是整個應用 Toast 還是會存在?

PhoneWindow的創建過程

我們以 Activity 的 setContentView 作為入口可以看到這么兩行代碼:

/*** Set the activity content from a layout resource. The resource will be* inflated, adding all top-level views to the activity.** @param layoutResID Resource ID to be inflated.** @see #setContentView(android.view.View)* @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)*/public void setContentView(@LayoutRes int layoutResID) {getWindow().setContentView(layoutResID);initWindowDecorActionBar();}

getWindow().setContentView(layoutResID) 這行代碼只是去解析我們的布局,沒干其他任何事情,這行代碼我就不再分析源碼了,今天的重點不在這里如果想了解請看這篇插件式換膚框架搭建 - setContentView源碼閱讀,getWindow() 返回的是 mWindow 而 mWindow 是在 attach 方法中實例化的:

final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window) {// 創建一個 PhoneWindow 實例mWindow = new PhoneWindow(this, window);// 設置一個 ControllerCallbackmWindow.setWindowControllerCallback(this);mWindow.setCallback(this);// 這個你看方法名就知道是什么意思了mWindow.setOnWindowDismissedCallback(this);// 給 Window 設置一個 WindowManager mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);// Activity 自己也有一個 WindowManagermWindowManager = mWindow.getWindowManager();}

那么 attach 方法到底是在什么時候調用的呢?在 ActivityThread 中的 performLaunchActivity 方法中調用的,這里涉及到 Activity 的啟動流程分析想了解請看這篇Android插件化架構 - Activity的啟動流程分析

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {Activity activity = null;try {// 利用反射創建 Activity 實例對象java.lang.ClassLoader cl = r.packageInfo.getClassLoader();activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException("Unable to instantiate activity " + component+ ": " + e.toString(), e);}}try {if (activity != null) {// 我們要找的方法在這里activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window);// 設置主題int theme = r.activityInfo.getThemeResource();if (theme != 0) {activity.setTheme(theme);}}} catch (SuperNotCalledException e) {throw e;} catch (Exception e) {if (!mInstrumentation.onException(activity, e)) {throw new RuntimeException("Unable to start activity " + component+ ": " + e.toString(), e);}}// 返回 Activity 實例return activity;}

目前我們只知道了通過 setContentView 方法會調用 mWindow 的 setContentView 方法,這個方法只是去解析我們的布局而已什么時都沒做,而 mWindow 的實例實在 activity 的 attach 方法中調用的,而這個方法是由 ActivityThread 調用的然后就沒有了,那么布局到底是怎么顯示的?

布局的測量和繪制過程

在Android插件化架構 - Activity的啟動流程分析中我們能夠在 ActivityThread 中找到 handleResumeActivity 這個方法:

final void handleResumeActivity(IBinder token,boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {// 先執行 Activity 的 onResume 生命周期方法// TODO Push resumeArgs into the activity for considerationr = performResumeActivity(token, clearHide, reason);if (r != null) {final Activity a = r.activity;if (r.window == null && !a.mFinished && willBeVisible) {r.window = r.activity.getWindow();// 獲取 Activity 也就是 PhoneWindow 的根布局View decor = r.window.getDecorView();// 設置為顯示decor.setVisibility(View.INVISIBLE);// 獲取 Activity 的 WindowManager 這個對象在上面的 Activity 的 attach 方法中賦值的ViewManager wm = a.getWindowManager();// 獲取PhoneWindow的 WindowManager.LayoutParams WindowManager.LayoutParams l = r.window.getAttributes();a.mDecor = decor;// 指定 type ,這是一個比較重要的概念,待會下面會介紹到 指定窗口的類型l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;l.softInputMode |= forwardBit;if (a.mVisibleFromClient && !a.mWindowAdded) {a.mWindowAdded = true;// 調用 ViewManager 的 addView 方法wm.addView(decor, l);}}} else {// If an exception was thrown when trying to resume, then// just end this activity.try {ActivityManagerNative.getDefault().finishActivity(token, Activity.RESULT_CANCELED, null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);} catch (RemoteException ex) {throw ex.rethrowFromSystemServer();}}}

最終調用了 ViewManager 的 addView 方法,但是我們發現 ViewManager 其實是個接口,所以我們得去找實現方法,是在上面 Activity 的 attach 方法通過 context.getSystemService(Context.WINDOW_SERVICE) 獲取的,找到 context 的實例類 ContextImpl 的 getSystemService 方法其實調用了 SystemServiceRegistry.getSystemService 方法:

/*** Gets a system service from a given context.*/public static Object getSystemService(ContextImpl ctx, String name) {ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);return fetcher != null ? fetcher.getService(ctx) : null;}

SYSTEM_SERVICE_FETCHERS 是一個靜態的 HashMap 對象,是通過靜態代碼塊賦值的。這里其實我們可以總結一下,通過 Context 獲取的系統服務其實早就被注冊和添加到 SYSTEM_SERVICE_FETCHERS 集合中了,這是典型的單例設計模式。至此我們總算找到了這個類 WindowManagerImpl 的 addView 方法。

@Overridepublic void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {applyDefaultToken(params);mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);}

WindowManagerImpl 是 ViewManager 的實現類卻把活交給了 WindowManagerGlobal 方法,而且我們發現 mGlobal 對象盡然是個單例,為什么要這么設計在文章中我就不做過多的講解了。我們看下 mGlobal 的 addView 方法:

public void addView(View view, ViewGroup.LayoutParams params,Display display, Window parentWindow) {// 一些參數的校驗// ......final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;if (parentWindow != null) {// 如果是子 View 需要調整一些布局的參數parentWindow.adjustLayoutParamsForSubWindow(wparams);} else {// If there's no parent, then hardware acceleration for this view is// set from the application's hardware acceleration setting.final Context context = view.getContext();if (context != null&& (context.getApplicationInfo().flags& ApplicationInfo.FLAG_HARDWARE_ACCELERATED) != 0) {wparams.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;}}ViewRootImpl root;View panelParentView = null;synchronized (mLock) {// 開始觀看系統屬性的變化。if (mSystemPropertyUpdater == null) {mSystemPropertyUpdater = new Runnable() {@Override public void run() {synchronized (mLock) {for (int i = mRoots.size() - 1; i >= 0; --i) {mRoots.get(i).loadSystemProperties();}}}};SystemProperties.addChangeCallback(mSystemPropertyUpdater);}// 通過View 去集合中查找位置,第一次添加肯定是 0int index = findViewLocked(view, false);if (index >= 0) {// 如果添加過的情況,判斷是不是正在銷毀中if (mDyingViews.contains(view)) {// Don't wait for MSG_DIE to make it's way through root's queue.mRoots.get(index).doDie();} else {// 如果不是正在銷毀,又添加過那么拋異常結束運行throw new IllegalStateException("View " + view+ " has already been added to the window manager.");}// The previous removeView() had not completed executing. Now it has.}// 如果是一個子窗口,我們去找到它的父窗口的 View // 窗口的類型,下面會介紹到if (wparams.type >= WindowManager.LayoutParams.FIRST_SUB_WINDOW &&wparams.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW) {final int count = mViews.size();for (int i = 0; i < count; i++) {if (mRoots.get(i).mWindow.asBinder() == wparams.token) {panelParentView = mViews.get(i);}}}// 構建ViewRootImpl,暫時不管ViewRootImpl是什么東西root = new ViewRootImpl(view.getContext(), display);// 給 View 設置 LayoutParamsview.setLayoutParams(wparams);// 下面是一些保存工作添加到集合,一一對應起來mViews.add(view);mRoots.add(root);mParams.add(wparams);}// 最后一行代碼,用來觸發做事// 將View顯示到手機上。setView方法比較復雜,走了這么就最重要的方法在這里面。try {root.setView(view, wparams, panelParentView);} catch (RuntimeException e) {// BadTokenException or InvalidDisplayException, clean up.synchronized (mLock) {final int index = findViewLocked(view, false);if (index >= 0) {removeViewLocked(index, true);}}throw e;}}

走了這么久最重要的方法其實就是 root.setView(view, wparams, panelParentView); 這行代碼,很復雜偏偏這個方法又是最主要的,希望我講得并不太深入而且通俗易懂。在分析這個之前我們先講一下上面反復出現的 type 屬性。

Window的三種類型

Window(窗口)是有類型的,而且上面我們也看到了不同的 type 會做不同的處理,Window 分為三種類型:系統 Window,應用程序 Window,子 Window

  • 常見的系統Window,比如在手機電量低的時候,會有一個提示電量低的Window,我們輸入文字的時候,會彈出輸入法Window,還有搜索條Window,來電顯示Window,Toast對應的Window,可以總結出來,系統Window是獨立與我們的應用程序的,對于應用程序而言,我們理論上是無法創建系統Window,因為沒有權限,這個權限只有系統進程有。所對應的層級區間是 2000 以上

  • 應用程序Window,比如 Activity 就是一個應用程序 Window 從上面源碼可以看到 type 給的是 TYPE_BASE_APPLICATION 。所對應的層級區間是 1 - 99

  • 子Window,所謂的子Window,是說這個Window必須要有一個父窗體,比如PopWindow,Dialog 等等 。所對應的層級區間是 1000 - 1999

那么每個層級具體有那些,請看 WindowManager.LayoutParams中的 type 值,這里我貼出來但是不做翻譯,因為我英語不好:

/*** Start of window types that represent normal application windows.*/public static final int FIRST_APPLICATION_WINDOW = 1;/*** Window type: an application window that serves as the "base" window* of the overall application; all other application windows will* appear on top of it.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_BASE_APPLICATION = 1;/*** Window type: a normal application window. The {@link #token} must be* an Activity token identifying who the window belongs to.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_APPLICATION = 2;/*** Window type: special application window that is displayed while the* application is starting. Not for use by applications themselves;* this is used by the system to display something until the* application can show its own windows.* In multiuser systems shows on all users' windows.*/public static final int TYPE_APPLICATION_STARTING = 3;/*** Window type: a variation on TYPE_APPLICATION that ensures the window* manager will wait for this window to be drawn before the app is shown.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_DRAWN_APPLICATION = 4;/*** End of types of application windows.*/public static final int LAST_APPLICATION_WINDOW = 99;/*** Start of types of sub-windows. The {@link #token} of these windows* must be set to the window they are attached to. These types of* windows are kept next to their attached window in Z-order, and their* coordinate space is relative to their attached window.*/public static final int FIRST_SUB_WINDOW = 1000;/*** Window type: a panel on top of an application window. These windows* appear on top of their attached window.*/public static final int TYPE_APPLICATION_PANEL = FIRST_SUB_WINDOW;/*** Window type: window for showing media (such as video). These windows* are displayed behind their attached window.*/public static final int TYPE_APPLICATION_MEDIA = FIRST_SUB_WINDOW + 1;/*** Window type: a sub-panel on top of an application window. These* windows are displayed on top their attached window and any* {@link #TYPE_APPLICATION_PANEL} panels.*/public static final int TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW + 2;/** Window type: like {@link #TYPE_APPLICATION_PANEL}, but layout* of the window happens as that of a top-level window, <em>not</em>* as a child of its container.*/public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW + 3;/*** Window type: window for showing overlays on top of media windows.* These windows are displayed between TYPE_APPLICATION_MEDIA and the* application window. They should be translucent to be useful. This* is a big ugly hack so:* @hide*/public static final int TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW + 4;/*** Window type: a above sub-panel on top of an application window and it's* sub-panel windows. These windows are displayed on top of their attached window* and any {@link #TYPE_APPLICATION_SUB_PANEL} panels.* @hide*/public static final int TYPE_APPLICATION_ABOVE_SUB_PANEL = FIRST_SUB_WINDOW + 5;/*** End of types of sub-windows.*/public static final int LAST_SUB_WINDOW = 1999;/*** Start of system-specific window types. These are not normally* created by applications.*/public static final int FIRST_SYSTEM_WINDOW = 2000;/*** Window type: the status bar. There can be only one status bar* window; it is placed at the top of the screen, and all other* windows are shifted down so they are below it.* In multiuser systems shows on all users' windows.*/public static final int TYPE_STATUS_BAR = FIRST_SYSTEM_WINDOW;/*** Window type: the search bar. There can be only one search bar* window; it is placed at the top of the screen.* In multiuser systems shows on all users' windows.*/public static final int TYPE_SEARCH_BAR = FIRST_SYSTEM_WINDOW+1;/*** Window type: phone. These are non-application windows providing* user interaction with the phone (in particular incoming calls).* These windows are normally placed above all applications, but behind* the status bar.* In multiuser systems shows on all users' windows.*/public static final int TYPE_PHONE = FIRST_SYSTEM_WINDOW+2;/*** Window type: system window, such as low power alert. These windows* are always on top of application windows.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_SYSTEM_ALERT = FIRST_SYSTEM_WINDOW+3;/*** Window type: keyguard window.* In multiuser systems shows on all users' windows.* @removed*/public static final int TYPE_KEYGUARD = FIRST_SYSTEM_WINDOW+4;/*** Window type: transient notifications.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_TOAST = FIRST_SYSTEM_WINDOW+5;/*** Window type: system overlay windows, which need to be displayed* on top of everything else. These windows must not take input* focus, or they will interfere with the keyguard.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+6;/*** Window type: priority phone UI, which needs to be displayed even if* the keyguard is active. These windows must not take input* focus, or they will interfere with the keyguard.* In multiuser systems shows on all users' windows.*/public static final int TYPE_PRIORITY_PHONE = FIRST_SYSTEM_WINDOW+7;/*** Window type: panel that slides out from the status bar* In multiuser systems shows on all users' windows.*/public static final int TYPE_SYSTEM_DIALOG = FIRST_SYSTEM_WINDOW+8;/*** Window type: dialogs that the keyguard shows* In multiuser systems shows on all users' windows.*/public static final int TYPE_KEYGUARD_DIALOG = FIRST_SYSTEM_WINDOW+9;/*** Window type: internal system error windows, appear on top of* everything they can.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_SYSTEM_ERROR = FIRST_SYSTEM_WINDOW+10;/*** Window type: internal input methods windows, which appear above* the normal UI. Application windows may be resized or panned to keep* the input focus visible while this window is displayed.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_INPUT_METHOD = FIRST_SYSTEM_WINDOW+11;/*** Window type: internal input methods dialog windows, which appear above* the current input method window.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12;/*** Window type: wallpaper window, placed behind any window that wants* to sit on top of the wallpaper.* In multiuser systems shows only on the owning user's window.*/public static final int TYPE_WALLPAPER = FIRST_SYSTEM_WINDOW+13;/*** Window type: panel that slides out from over the status bar* In multiuser systems shows on all users' windows.*/public static final int TYPE_STATUS_BAR_PANEL = FIRST_SYSTEM_WINDOW+14;/*** Window type: secure system overlay windows, which need to be displayed* on top of everything else. These windows must not take input* focus, or they will interfere with the keyguard.** This is exactly like {@link #TYPE_SYSTEM_OVERLAY} except that only the* system itself is allowed to create these overlays. Applications cannot* obtain permission to create secure system overlays.** In multiuser systems shows only on the owning user's window.* @hide*/public static final int TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15;/*** Window type: the drag-and-drop pseudowindow. There is only one* drag layer (at most), and it is placed on top of all other windows.* In multiuser systems shows only on the owning user's window.* @hide*/public static final int TYPE_DRAG = FIRST_SYSTEM_WINDOW+16;/*** Window type: panel that slides out from under the status bar* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_STATUS_BAR_SUB_PANEL = FIRST_SYSTEM_WINDOW+17;/*** Window type: (mouse) pointer* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_POINTER = FIRST_SYSTEM_WINDOW+18;/*** Window type: Navigation bar (when distinct from status bar)* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW+19;/*** Window type: The volume level overlay/dialog shown when the user* changes the system volume.* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_VOLUME_OVERLAY = FIRST_SYSTEM_WINDOW+20;/*** Window type: The boot progress dialog, goes on top of everything* in the world.* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW+21;/*** Window type to consume input events when the systemUI bars are hidden.* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_INPUT_CONSUMER = FIRST_SYSTEM_WINDOW+22;/*** Window type: Dreams (screen saver) window, just above keyguard.* In multiuser systems shows only on the owning user's window.* @hide*/public static final int TYPE_DREAM = FIRST_SYSTEM_WINDOW+23;/*** Window type: Navigation bar panel (when navigation bar is distinct from status bar)* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_NAVIGATION_BAR_PANEL = FIRST_SYSTEM_WINDOW+24;/*** Window type: Display overlay window. Used to simulate secondary display devices.* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_DISPLAY_OVERLAY = FIRST_SYSTEM_WINDOW+26;/*** Window type: Magnification overlay window. Used to highlight the magnified* portion of a display when accessibility magnification is enabled.* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_MAGNIFICATION_OVERLAY = FIRST_SYSTEM_WINDOW+27;/*** Window type: keyguard scrim window. Shows if keyguard needs to be restarted.* In multiuser systems shows on all users' windows.* @hide*/public static final int TYPE_KEYGUARD_SCRIM = FIRST_SYSTEM_WINDOW+29;/*** Window type: Window for Presentation on top of private* virtual display.*/public static final int TYPE_PRIVATE_PRESENTATION = FIRST_SYSTEM_WINDOW+30;/*** Window type: Windows in the voice interaction layer.* @hide*/public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31;/*** Window type: Windows that are overlaid <em>only</em> by a connected {@link* android.accessibilityservice.AccessibilityService} for interception of* user interactions without changing the windows an accessibility service* can introspect. In particular, an accessibility service can introspect* only windows that a sighted user can interact with which is they can touch* these windows or can type into these windows. For example, if there* is a full screen accessibility overlay that is touchable, the windows* below it will be introspectable by an accessibility service even though* they are covered by a touchable window.*/public static final int TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32;/*** Window type: Starting window for voice interaction layer.* @hide*/public static final int TYPE_VOICE_INTERACTION_STARTING = FIRST_SYSTEM_WINDOW+33;/*** Window for displaying a handle used for resizing docked stacks. This window is owned* by the system process.* @hide*/public static final int TYPE_DOCK_DIVIDER = FIRST_SYSTEM_WINDOW+34;/*** Window type: like {@link #TYPE_APPLICATION_ATTACHED_DIALOG}, but used* by Quick Settings Tiles.* @hide*/public static final int TYPE_QS_DIALOG = FIRST_SYSTEM_WINDOW+35;/*** Window type: shares similar characteristics with {@link #TYPE_DREAM}. The layer is* reserved for screenshot region selection. These windows must not take input focus.* @hide*/public static final int TYPE_SCREENSHOT = FIRST_SYSTEM_WINDOW + 36;/*** End of types of system windows.*/public static final int LAST_SYSTEM_WINDOW = 2999;

窗口與WindowManagerService服務的連接過程

回到 ViewRootImpl 中的 setView 方法:

/*** We have one child*/public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {synchronized (this) {if (mView == null) {mView = view;// ......// Schedule the first layout -before- adding to the window// manager, to make sure we do the relayout before receiving// any other events from the system.// 布局測量繪制是從這個方法開始的requestLayout();try {mOrigWindowType = mWindowAttributes.type;mAttachInfo.mRecomputeGlobalAttributes = true;collectViewAttributes();res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,getHostVisibility(), mDisplay.getDisplayId(),mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,mAttachInfo.mOutsets, mInputChannel);} catch (RemoteException e) {mAdded = false;mView = null;mAttachInfo.mRootView = null;mInputChannel = null;mFallbackEventHandler.setView(null);unscheduleTraversals();setAccessibilityFocus(null, null);throw new RuntimeException("Adding window failed", e);} finally {if (restore) {attrs.restore();}}// ......}}

requestLayout() 這個方法很有含金量,如果想了解看下這篇 源碼解析 - View的繪制流程 ,我們主要還是分析mWindowSession.addToDisplay 方法,mWindowSession 又是什么呢?看到 Session 其實還是知道什么意思,是不是真的和網絡的 Session 差不多呢?mWindowSession 是通過 WindowManagerGlobal.getWindowSession(); 獲取的,我們去看下:

public static IWindowSession getWindowSession() {synchronized (WindowManagerGlobal.class) {if (sWindowSession == null) {try {InputMethodManager imm = InputMethodManager.getInstance();IWindowManager windowManager = getWindowManagerService();sWindowSession = windowManager.openSession(new IWindowSessionCallback.Stub() {@Overridepublic void onAnimatorScaleChanged(float scale) {ValueAnimator.setDurationScale(scale);}},imm.getClient(), imm.getInputContext());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}return sWindowSession;}}public static IWindowManager getWindowManagerService() {synchronized (WindowManagerGlobal.class) {if (sWindowManagerService == null) {sWindowManagerService = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));try {sWindowManagerService = getWindowManagerService();ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}return sWindowManagerService;}}

這又是一個典型的 IPC 的通信機制,和 AMS 非常的類似想了解看下這篇 Android進程間的通信 - IPC(機制)Binder的原理和源碼閱讀 ,現在我們去服務端 WindowManagerService 的 openSession 方法:

@Overridepublic IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client,IInputContext inputContext) {if (client == null) throw new IllegalArgumentException("null client");if (inputContext == null) throw new IllegalArgumentException("null inputContext");Session session = new Session(this, callback, client, inputContext);return session;}

Session我們總算是獲取到了,服務端 WindowManagerService 創建了一個 Session 對象返回回來了,接下來我們發現 Session 的 addToDisplay 方法來到了 WindowManager 的 addWindow 方法,相信應該差不多快完了吧,這不是人干的事:

public int addWindow(Session session, IWindow client, int seq,WindowManager.LayoutParams attrs, int viewVisibility, int displayId,Rect outContentInsets, Rect outStableInsets, Rect outOutsets,InputChannel outInputChannel) {...... WindowState attachedWindow = null; final int type = attrs.type;synchronized(mWindowMap) { ...... if (mWindowMap.containsKey(client.asBinder())) { ...... return WindowManagerImpl.ADD_DUPLICATE_ADD; }

這段代碼首先在WindowManagerService類的成員變量mWindowMap所描述的一個HashMap中檢查是否存在一個與參數client所對應的WindowState對象,如果已經存在,那么就說明WindowManagerService服務已經為它創建過一個WindowState對象了,因此,這里就不會繼續往前執行,而是直接返回一個錯誤碼WindowManagerImpl.ADD_DUPLICATE_ADD。我們繼續往前看代碼:

if (attrs.type >= FIRST_SUB_WINDOW && attrs.type <= LAST_SUB_WINDOW) { attachedWindow = windowForClientLocked(null, attrs.token, false); if (attachedWindow == null) { ...... return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN; } if (attachedWindow.mAttrs.type >= FIRST_SUB_WINDOW && attachedWindow.mAttrs.type <= LAST_SUB_WINDOW) { ...... return WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN; } }

參數attrs指向的是一個WindowManager.LayoutParams對象,用來描述正在啟動的Activity組件的UI布局,當它的成員變量type的值大于等于FIRST_SUB_WINDOW并且小于等于LAST_SUB_WINDOW的時候,就說明現在要增加的是一個子窗口。在這種情況下,就必須要指定一個父窗口,而這個父窗口是通過數attrs指向的是一個WindowManager.LayoutParams對象的成員變量token來指定的,因此,這段代碼就會調用WindowManagerService類的另外一個成員函數windowForClientLocked來獲得用來描述這個父窗口的一個WindowState對象,并且保存在變量attachedWindow。

如果得到變量attachedWindow的值等于null,那么就說明父窗口不存在,這是不允許的,因此,函數就不會繼續向前執行,而是直接返回一個錯誤碼WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN。另一方面,如果變量attachedWindow的值不等于null,但是它的成員變量mAttrs所指向的一個WindowManager.LayoutParams對象的成員變量type的值也是大于等于FIRST_SUB_WINDOW并且小于等于LAST_SUB_WINDOW,那么也說明找到的父窗口也是一個子窗口,這種情況也是不允許的,因此,函數就不會繼續向前執行,而是直接返回一個錯誤碼WindowManagerImpl.ADD_BAD_SUBWINDOW_TOKEN。

繼續看代碼:

// 一些檢查合法的代碼win = new WindowState(session, client, token, attachedWindow, attrs, viewVisibility); ...... mPolicy.adjustWindowParamsLw(win.mAttrs); res = mPolicy.prepareAddWindowLw(win, attrs); if (res != WindowManagerImpl.ADD_OKAY) { return res; }

通過上面的合法性檢查之后,這里就可以為正在增加的窗口創建一個WindowState對象了。 WindowManagerService類的成員變量mPolicy指向的是一個實現了WindowManagerPolicy接口的窗口管理策略器。在Phone平臺中,這個窗口管理策略器是由com.android.internal.policy.impl.PhoneWindowManager來實現的,它負責對系統中的窗口實現制定一些規則。這里主要是調用窗口管理策略器的成員函數adjustWindowParamsLw來調整當前正在增加的窗口的布局參數,以及調用成員函數prepareAddWindowLw來檢查當前應用程序進程請求增加的窗口是否是合法的。如果不是合法的,即變量res的值不等于WindowManagerImpl.ADD_OKAY,那么函數就不會繼續向前執行,而直接返回錯誤碼res。

我們就先看到這里了,你甚至還可以在去了解 WindowState 的成員變量都有一些啥作用,又或者是那些合法的檢查代碼都有什么用等等,最后我再畫一張草圖:


我花了大概半個多月的時間才勉強看懂一些源碼,當然包括這篇文章中的所有源碼鏈接,如果看不太懂需要多花些時間,如果文字讓你受不了可以看看我的直播視頻,同時這也是自定義View部分的最后一篇文章了。

所有分享大綱:Android進階之旅 - 自定義View篇

視頻講解地址:http://pan.baidu.com/s/1pLNXkxl

總結

以上是生活随笔為你收集整理的源码阅读分析 - Window底层原理与系统架构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

69av国产| 国产91精品欧美 | www激情久久 | 国产一区免费在线观看 | 欧美 日韩 国产 中文字幕 | 91亚色在线观看 | 成人黄色在线 | 97国产精品视频 | 久草在线一免费新视频 | 欧美性高跟鞋xxxxhd | 免费在线观看亚洲视频 | 欧美国产日韩激情 | 久久综合欧美精品亚洲一区 | av成人免费 | 97超碰中文字幕 | 中国一级片免费看 | 日韩精品黄 | 精品久久1 | 天堂视频中文在线 | 97在线成人 | 丁香六月婷婷开心婷婷网 | 又黄又爽又刺激视频 | 日本h在线播放 | 日韩特级黄色片 | 免费的国产精品 | 日韩精品免费一线在线观看 | 中文一区在线观看 | 久久99精品国产麻豆婷婷 | 久久久蜜桃 | 国内毛片毛片 | 色狠狠一区二区 | 精品视频在线看 | 久久97久久 | 国产视频精选在线 | 日韩亚洲国产精品 | 欧美精品在线观看免费 | 久久福利综合 | 国产精品久久久久久久久久三级 | 高潮毛片无遮挡高清免费 | 伊人国产在线观看 | 黄色片软件网站 | 欧美成人精品欧美一级乱 | 国产精品久久久久久久久毛片 | 欧美a视频在线观看 | 天天做日日爱夜夜爽 | 欧美精品一区二区在线观看 | 国产最顶级的黄色片在线免费观看 | 欧美日韩久久不卡 | 免费看片色 | 在线观看中文字幕一区二区 | 在线观看日韩国产 | 国产精品免费成人 | 色老板在线视频 | 亚在线播放中文视频 | 三级性生活视频 | 久久一区二区免费视频 | 亚洲一区精品人人爽人人躁 | 色婷婷激情四射 | 成人国产电影在线观看 | 久久国产精品久久精品国产演员表 | 亚洲精品视频在线播放 | 国产精品久久嫩一区二区免费 | 国产丝袜制服在线 | 免费91麻豆精品国产自产在线观看 | 狠狠色狠狠色综合日日小说 | 欧美福利在线播放 | 激情自拍av | 开心色插 | 久久视频免费 | 丁香婷婷久久久综合精品国产 | 91精品办公室少妇高潮对白 | 精品一区二区三区四区在线 | www.91国产 | 国语久久 | 久久综合偷偷噜噜噜色 | 91看片淫黄大片一级在线观看 | 夜夜躁日日躁 | 欧美一二三区在线播放 | 超碰97中文 | 五月婷婷在线观看 | 超碰在线观看av | 五月天堂网 | www.888.av | 在线一区电影 | 日韩中文字幕a | 伊人开心激情 | 欧美另类一二三四区 | 高清av影院| 亚洲v欧美v国产v在线观看 | 911香蕉| 欧美一进一出抽搐大尺度视频 | 日韩欧美综合在线视频 | 午夜电影 电影 | 青青河边草免费 | 欧美极品少妇xxxx | 一二三久久久 | 午夜免费福利视频 | 久久精品精品 | 免费看av片网站 | 久久成人18免费网站 | 91九色porny蝌蚪视频 | 色 免费观看| 亚洲干视频在线观看 | 六月丁香在线观看 | 久久精选视频 | 西西大胆免费视频 | 欧美日韩在线观看一区 | 午夜91视频| 国产高清网站 | 国产1级视频 | 国产高清在线一区 | 中文字幕中文字幕中文字幕 | 天天艹| 国产午夜精品一区二区三区在线观看 | 97国产小视频 | 99精品在线免费观看 | 日本aaaa级毛片在线看 | 亚洲黄色三级 | 免费黄色小网站 | av成年人电影 | 亚洲闷骚少妇在线观看网站 | 永久中文字幕 | 最近日本韩国中文字幕 | 亚洲国产中文字幕在线观看 | 狠狠躁天天躁 | 成人黄色小说网 | 精品一区二区在线看 | 国产亚洲精品久久久久久网站 | 一区二区三区www | 欧美色综合天天久久综合精品 | 色综合网在线 | 亚洲成人蜜桃 | 九色精品免费永久在线 | 国产护士hd高朝护士1 | 美女视频免费精品 | 91视频传媒 | 国产一级在线看 | 国产第一二区 | 开心激情综合网 | 国产黄色精品视频 | 在线黄色国产电影 | 免费视频网 | 欧美一二三四在线 | av在线小说 | 韩国av三级 | 涩涩网站在线观看 | 日韩有码第一页 | 人人爱人人爽 | 超碰人人超| 在线视频精品 | 国产日韩欧美网站 | 色婷婷中文 | 色精品视频 | 在线观看网站av | 天天色 天天 | 亚洲三区在线 | 亚洲精品国产精品99久久 | 日本黄色片一区二区 | 精品uu| 成人免费观看网址 | 久久久精品二区 | 在线国产小视频 | 伊人国产视频 | 亚洲精品色 | 9999在线视频 | 久久三级毛片 | 日韩午夜精品福利 | 99综合电影在线视频 | 久久国产精品小视频 | 国产中文字幕一区二区三区 | 超碰在线94 | 国内精品毛片 | 欧美一级专区免费大片 | 九九精品在线观看 | 五月天六月丁香 | 亚洲最大av网站 | 精品在线免费视频 | 精品在线观看免费 | 亚洲影院色 | 97精品国产91久久久久久久 | 欧美日韩伦理在线 | 久久高清精品 | 天天色天天干天天色 | 国产乱码精品一区二区三区介绍 | 国产精品国产自产拍高清av | 久久99精品波多结衣一区 | 狠狠干我 | 国产精品九九热 | 国产精品99在线观看 | 欧美日韩国产一二三区 | 免费看的黄色 | 久久不卡av | 精品高清美女精品国产区 | 婷婷色中文 | 国产色区 | 日本一区二区不卡高清 | 欧美性生活大片 | 成人cosplay福利网站 | 亚洲综合国产精品 | 在线一二三区 | 去干成人网 | 99色国产 | 亚洲欧美成人 | 婷婷五月色综合 | 999热视频 | 天天操天天干天天干 | 色片网站在线观看 | 福利一区在线 | 免费电影播放 | 国产视频资源在线观看 | 日韩字幕| 在线免费试看 | 久草视频免费 | 久久久久国产精品一区二区 | 亚洲美女免费视频 | 一区二区三区四区五区在线视频 | 91亚洲视频在线观看 | 国产精品亚洲人在线观看 | 九九热免费在线视频 | 国产黄色在线观看 | 成人一级免费视频 | 欧美日韩国产mv | 久草视频免费在线观看 | 九九热视频在线免费观看 | 亚洲黄色免费网站 | 99精品国产免费久久久久久下载 | 91福利视频在线 | 久久99国产精品 | 欧美日韩不卡一区二区三区 | 国产亚洲精品久久久久久无几年桃 | 欧美精品首页 | www五月天婷婷 | 成年人在线免费视频观看 | 中文超碰字幕 | bbw av | 精品国产成人 | 日韩美女免费线视频 | 亚洲波多野结衣 | 色偷偷88888欧美精品久久久 | 成年人在线视频观看 | 一级黄色毛片 | 成人免费视频网站 | 日韩在线不卡视频 | 欧美日韩在线第一页 | 日韩欧美在线免费 | 国产一区福利 | 最新日韩精品 | 久久精品美女视频 | 中文字幕丝袜美腿 | 久青草视频在线观看 | 国产精品黄色 | 欧美一区二区三区在线视频观看 | 国产精品久久久久永久免费看 | 国产精成人品免费观看 | 丁香激情五月 | 亚洲成aⅴ人在线观看 | 欧美aa在线 | 久久男人中文字幕资源站 | 天堂av在线网址 | 干亚洲少妇 | 午夜av不卡 | 国产精品国产三级在线专区 | 在线免费观看国产精品 | 亚洲天堂网在线播放 | 国产精品系列在线播放 | 国产一区av在线 | 亚洲另类xxxx | 国产一区不卡在线 | 亚洲国产网站 | 成人午夜免费剧场 | 中文字幕欧美日韩va免费视频 | 成人教育av | 亚洲精品视频在线观看免费视频 | 欧美国产在线看 | 日韩精品首页 | 又黄又爽的视频在线观看网站 | av资源中文字幕 | 日韩免费三级 | 免费性网站 | 国产字幕在线播放 | 久久久国产精品免费 | 美女网站免费福利视频 | 日韩视频二区 | 亚洲免费在线视频 | 91精品国产91久久久久久三级 | 日韩视频a | 视频精品一区二区三区 | 99久久99 | 99九九99九九九视频精品 | 久久久亚洲精品 | 久久久久99精品国产片 | av免费成人| 国产精品成人自产拍在线观看 | 日韩欧美v| 99热国产在线观看 | 91麻豆免费看| 国产精品黑丝在线观看 | 亚洲三级在线 | 成人一级片在线观看 | 国产xvideos免费视频播放 | 精品99视频 | 在线黄色免费av | 美女网站一区 | 天天射网站 | 亚洲精品动漫成人3d无尽在线 | 久久综合99 | 欧美日韩成人 | 91黄色在线视频 | 久久爱资源网 | 亚洲国产日韩在线 | 国产护士av | 亚洲电影一级黄 | 午夜久久久久久久久久影院 | 天天干天天草 | 久久久久久久电影 | 精品亚洲成a人在线观看 | 免费视频网 | 亚洲免费永久精品国产 | 激情文学综合丁香 | 婷婷久草| 中文字幕乱码电影 | 亚洲综合最新在线 | 免费av片在线 | 天天干,天天射,天天操,天天摸 | 久久国产香蕉视频 | 日本黄色特级片 | 亚洲精品国产区 | 激情婷婷综合网 | 美女黄久久 | 国产在线看一区 | 国产亚洲无 | 日av免费| 九草视频在线观看 | 日韩高清毛片 | 日韩欧美视频在线免费观看 | 国产一区观看 | 久久免费国产精品 | 日本激情视频中文字幕 | 在线观看中文字幕第一页 | 精品伊人久久久 | 日本在线视频网址 | 欧美一区,二区 | 国产精品美女视频网站 | 激情综合电影网 | 在线看免费 | 欧美高清视频不卡网 | 亚洲九九 | 97综合在线 | 欧美激情视频免费看 | 日韩深夜在线观看 | 99看视频在线观看 | 免费福利视频网站 | av福利在线导航 | 亚洲精品18日本一区app | 97看片| 国产原创av片| 欧美日韩一区二区三区不卡 | 久久免费的精品国产v∧ | 国产成人精品一区二区三区网站观看 | 久久久这里有精品 | 国产网站在线免费观看 | av 一区 二区 久久 | 国产超碰在线观看 | 91网在线 | 在线观看黄色免费视频 | 国产99久久 | 国产aaa毛片| 久草在线免费色站 | 在线精品视频免费播放 | 国产精品久久一区二区无卡 | 国产成人福利在线 | 91桃色在线免费观看 | 日本69hd| 日韩av成人免费看 | 看片网站黄色 | 亚洲精品字幕在线 | 天天操狠狠操网站 | 精品国产伦一区二区三区观看说明 | 四虎影视成人永久免费观看亚洲欧美 | 91最新地址永久入口 | 国产精品久久久久久久久久久久久 | 久久毛片高清国产 | 日韩在线电影一区二区 | 久草视频在线资源 | 最近中文字幕完整高清 | 美女在线免费观看视频 | 国产一区免费看 | 亚洲激情精品 | 国产精品18久久久久久久久 | 一区二区三区四区五区在线 | 天天综合网 天天综合色 | 婷婷丁香在线视频 | 99re国产视频 | 久草在在线视频 | 在线观看爱爱视频 | 成人av片免费看 | 97在线观看视频 | 成人一级免费视频 | 99热九九这里只有精品10 | 亚洲天天干| 天天天射 | 国产手机免费视频 | 97精品国产91久久久久久 | 久久久鲁 | 午夜精品一区二区三区四区 | 亚洲春色成人 | 三级动图 | 国产成人精品一区二区三区 | 一区二区三区在线看 | 性色xxxxhd | 中文字幕一二三区 | 亚洲午夜精品久久久久久久久久久久 | 91综合视频在线观看 | 欧美地下肉体性派对 | 三级黄免费看 | 91片在线观看 | av在线播放快速免费阴 | 中文字幕在线观看第二页 | 国产高清av免费在线观看 | 在线看片日韩 | 久久精品网站免费观看 | 久久综合狠狠狠色97 | 91精品对白一区国产伦 | 国产麻豆精品传媒av国产下载 | 亚洲黄色在线播放 | 午夜精品久久久久久久久久久久久久 | 黄网站免费看 | 亚洲免费高清视频 | 香蕉影视app | 精品国产乱码一区二区三区在线 | 成人在线免费小视频 | 久久精品99精品国产香蕉 | 天天做日日做天天爽视频免费 | 日日干日日 | 国产日韩欧美在线一区 | 久久综合一本 | 丁香五月亚洲综合在线 | 国产色在线| www久久久| 色婷婷成人网 | 天天插天天干 | 国产成人综合精品 | 亚洲理论影院 | 天天射天天射 | 婷婷激情综合五月天 | www最近高清中文国语在线观看 | 免费高清在线观看成人 | 国产美女视频 | 超碰97国产 | 久久国产手机看片 | 天天爽天天射 | 亚洲一区二区高潮无套美女 | 日韩爱爱网站 | 久久国产午夜精品理论片最新版本 | 免费午夜网站 | 成人h视频在线 | 在线观看av国产 | 国产另类av| 在线观看va | 最新国产中文字幕 | 91麻豆免费视频 | 91久久久久久久一区二区 | 五月婷婷一区二区三区 | 日韩毛片一区 | 天天射综合网站 | 日韩一区二区三区不卡 | 中文字幕av电影下载 | 免费在线观看日韩欧美 | 五月天中文在线 | 久久久久久久久久久精 | 久久免费视频国产 | 亚洲美女精品 | 免费高清在线观看成人 | 一区二区国产精品 | 国产亚洲精品日韩在线tv黄 | 天天色视频 | 免费成人在线视频网站 | 欧美成人精品在线 | 狠狠狠狠狠狠操 | 天堂中文在线播放 | 欧美日韩亚洲一 | 999电影免费在线观看 | 色吧久久 | 91精品国产欧美一区二区成人 | 欧美日韩高清一区二区 国产亚洲免费看 | 国内久久久久 | 99久久精品久久亚洲精品 | 色多视频在线观看 | 中日韩欧美精彩视频 | 国产精品白浆视频 | 天天操天天操天天操天天操天天操 | 亚洲影院天堂 | 日韩中文字幕a | 欧美韩国在线 | 正在播放国产一区 | 久久久久免费观看 | 欧美狠狠操 | 视频在线观看91 | 国产色拍拍拍拍在线精品 | 久久久久久久久久福利 | 人人添人人澡人人澡人人人爽 | 国产精品高潮在线观看 | 日韩69视频 | 亚洲一区欧美精品 | 久久激情五月丁香伊人 | 天天操天天曰 | 久久国产精品99久久久久久丝袜 | 国产精品6999成人免费视频 | 欧美日韩激情网 | 久久久久久久久久久久国产精品 | 日本中文字幕观看 | 国产视频中文字幕 | 在线中文字母电影观看 | 福利电影一区二区 | 96视频免费在线观看 | 中文字幕色网站 | 成人黄色片免费 | 日韩黄色免费看 | 黄色aaa毛片 | 久久激五月天综合精品 | 能在线看的av | 日韩免费一二三区 | 亚洲免费av电影 | 免费黄色小网站 | 99色免费 | 国产精品乱码一区二区视频 | 国产精品毛片网 | 免费在线观看成人小视频 | 精品天堂av | 日日夜夜免费精品视频 | 在线观看一级片 | 这里只有精品视频在线 | 久草在线视频网 | 久久精品久久久久久久 | 另类老妇性bbwbbw高清 | 五月婷婷中文网 | 久久黄色小说视频 | 97碰在线 | 国产一性一爱一乱一交 | 国产精品免费视频观看 | 久久国产精品色婷婷 | 97人人澡人人添人人爽超碰 | 日韩午夜电影 | 成人久久久久久久久久 | 日韩精品一区二区三区外面 | 亚洲精品午夜久久久久久久 | 97在线免费 | 超碰.com| 国产精品久久久久久妇 | 久久久久久久久久久久国产精品 | 国产高清视频在线播放 | 99免在线观看免费视频高清 | 久艹视频在线免费观看 | 欧美孕妇与黑人孕交 | 伊人官网| 超碰在线1 | 午夜一级免费电影 | 国产黄a三级三级三级三级三级 | 97人人艹| 在线观看黄色国产 | 精品999在线观看 | 在线观看久草 | av电影一区二区三区 | 在线观看日韩精品 | jizz999| 国产成人av在线影院 | 国产在线观看污片 | 亚洲欧美乱综合图片区小说区 | 欧美激情综合网 | av国产在线观看 | 91麻豆精品国产午夜天堂 | 九九久久久久久久久激情 | 99精品免费久久久久久久久日本 | 91视频啪 | 91麻豆精品国产自产在线游戏 | 天堂av在线中文在线 | 色综合久久久 | 日操操 | 婷婷在线综合 | 国产成人黄色 | 九九精品毛片 | 中文字幕精 | www.天天综合 | 国产爽妇网 | 国产传媒一区在线 | 日日干av | 国产精品不卡一区 | 麻豆久久久 | 欧美日韩在线视频一区二区 | 久久在线播放 | 99在线视频网站 | 婷婷伊人综合亚洲综合网 | 国产在线视频一区二区三区 | 成人动漫一区二区 | 美女福利视频一区二区 | 久久久久福利视频 | 国产亚洲精品日韩在线tv黄 | 99热日本 | 丁香高清视频在线看看 | 中文字幕在线播放视频 | 一区二区三区国产欧美 | 91精品国产麻豆国产自产影视 | 四虎免费在线观看视频 | 激情五月婷婷激情 | 国产精品中文字幕在线播放 | 久久新 | 日本久久成人中文字幕电影 | av日韩不卡| 免费美女久久99 | 日韩成片| 中文字幕在线观看资源 | 99麻豆久久久国产精品免费 | 国产一区二区三区在线免费观看 | 国产亚洲在线视频 | 国产视频99| 日韩午夜电影院 | 99免费在线视频 | 免费成人看片 | 在线小视频| 在线国产一区二区 | 国产精品成人一区二区三区吃奶 | 99精品免费久久久久久日本 | 欧美a影视 | 久久久91精品国产一区二区精品 | 欧美二区视频 | 欧美坐爱视频 | 一区二区精品在线视频 | 久草在线免费新视频 | 国产精品免费一区二区三区在线观看 | www.综合网.com| 91在线视频导航 | 亚洲作爱视频 | 特级毛片在线 | 亚洲综合在线一区二区三区 | av片子在线观看 | 久久国产精品久久精品 | 欧美精品乱码99久久影院 | 国产精品久久99综合免费观看尤物 | 亚洲精品综合在线 | 久久久免费精品国产一区二区 | 日本中文字幕视频 | 日日夜夜免费精品 | 人人精品久久 | 国产91精品欧美 | 久久黄页 | 蜜臀久久99静品久久久久久 | 99国产成+人+综合+亚洲 欧美 | 99久久99久久精品国产片果冰 | a视频在线播放 | 日本黄色一级电影 | 婷婷综合久久 | 欧洲精品久久久久毛片完整版 | 欧美日韩一二三四区 | 久久久久久久免费观看 | 久草剧场 | 久久久免费看 | 成人久久18免费网站图片 | 91网在线看 | 欧美激情第一页xxx 午夜性福利 | 国产手机视频精品 | 国产精品久久久视频 | 丁香综合激情 | 日韩三级视频在线看 | 久久精品亚洲一区二区三区观看模式 | 国产精品久久久久久久久久尿 | 免费在线观看av电影 | 国产xxxxx在线观看 | 视频一区二区精品 | 天天曰天天爽 | 最近中文字幕第一页 | 日本视频精品 | 免费网站在线观看人 | 国产精品视频全国免费观看 | 亚洲精品成人在线 | 免费在线激情视频 | 日韩一级电影在线观看 | 91x色| 精品久久中文 | 中文字幕激情 | 日本一区二区高清不卡 | 国产视频一区二区在线 | 成人久久久久久久久 | 精品视频免费看 | 国产原创在线 | 91黄色成人 | 久久精品亚洲一区二区三区观看模式 | 国产在线国产 | 蜜臀av性久久久久av蜜臀三区 | 97超碰人人澡人人爱 | 午夜久久影视 | 日韩激情小视频 | 国产福利91精品张津瑜 | 91精品在线观看入口 | 国产 日韩 在线 亚洲 字幕 中文 | 亚洲精品av中文字幕在线在线 | 激情小说 五月 | 中文字幕亚洲字幕 | 日本99热| 国产黄色片一级三级 | 日韩免费久久 | 中文字幕在线有码 | 免费看片日韩 | 欧美日韩破处 | 黄网站www | 国产999久久久 | www.看片网站| 久久精品视频中文字幕 | 在线观看亚洲视频 | 成人污视频在线观看 | 四虎影视成人永久免费观看亚洲欧美 | 国产成人在线观看免费 | 亚洲爱视频| 香蕉久草在线 | 久久99精品视频 | 成人黄视频 | 久久精品视频观看 | 91丝袜美腿 | 三级黄色片子 | 国产日韩高清在线 | 在线观看午夜 | a在线播放| 麻豆视频在线免费 | 欧美成人性网 | 久久综合桃花 | 欧美日韩免费一区二区 | 日本精品视频一区二区 | 最近中文字幕mv | 欧美一级视频免费看 | 婷婷在线精品视频 | 国产午夜三级一二三区 | 久久久久久久久影院 | 国产精品18久久久久久久 | 久久视频中文字幕 | 在线视频久久 | 99久久99视频 | 91av在线视频播放 | 国产美女视频 | 亚洲天堂网视频在线观看 | 黄色国产精品 | 在线播放亚洲激情 | 免费观看www小视频的软件 | 狠狠干电影 | 国产在线精品播放 | 亚洲三级黄色 | 91精品啪在线观看国产81旧版 | 久久精品麻豆 | 久久国产精品免费 | 五月天婷婷在线观看视频 | 激情综合交| 国产精品涩涩屋www在线观看 | 精品久久久亚洲 | 欧美91片| 色综合久久久久久久 | 国产黄色片一级三级 | 在线观看日韩国产 | 九九热精 | 可以免费观看的av片 | 日韩大片在线免费观看 | 一级片免费观看 | 色天天综合久久久久综合片 | 91精品国产麻豆国产自产影视 | www日韩高清 | 欧美韩日在线 | 国产在线一区二区 | 夜夜夜影院 | 中文在线a∨在线 | 免费日韩一区二区三区 | 美国av大片 | 国产成人精品日本亚洲999 | 91精品国产三级a在线观看 | 国产精品一区二区三区99 | 国产69久久久欧美一级 | 天天操狠狠操 | 欧美一区二视频在线免费观看 | 91成熟丰满女人少妇 | 免费成人av在线 | 日韩最新在线视频 | 国产精品一区二区美女视频免费看 | 成人一区电影 | 三上悠亚一区二区在线观看 | 久久视| 久草网在线 | 国产在线2020| 久久夜视频 | www.久久久精品 | 曰本免费av | 午夜免费在线观看 | 日韩免费视频播放 | 国产99久久久国产精品免费二区 | 最近2019中文免费高清视频观看www99 | av官网在线| 人人爽人人 | 亚洲每日更新 | 97在线观看免费观看 | 久久这里有精品 | 久久高清片 | 精品一二三四五区 | 久久伊人爱 | 亚洲精品午夜国产va久久成人 | 亚洲精品在线视频 | 色999五月色 | 天天爱天天干天天爽 | 国产偷在线 | 在线a亚洲视频播放在线观看 | 亚洲影视九九影院在线观看 | 国产精品电影一区二区 | 国产精品久久久久aaaa | 日本特黄特色aaa大片免费 | 91理论电影| 免费在线电影网址大全 | 黄色大全免费网站 | 日日射天天射 | 91资源在线视频 | 亚洲情感电影大片 | 日韩免费电影网站 | 国产精品一区二区av日韩在线 | 五月天丁香 | 日韩在线精品一区 | 久久精品久久久精品美女 | 在线免费亚洲 | av电影免费观看 | 91在线免费观看国产 | 久久久国产精品网站 | 中文字幕日韩一区二区三区不卡 | 92精品国产成人观看免费 | 最新91在线视频 | 日本中文字幕在线看 | 婷婷午夜| 91喷水| 国产永久免费高清在线观看视频 | 国产精品99久久久 | 成人久久免费 | 成片免费观看视频 | 91久久在线观看 | 91一区二区三区久久久久国产乱 | 精品在线99 | 亚洲精品乱码久久久久久按摩 | 夜夜视频资源 | 午夜私人影院久久久久 | 九九热中文字幕 | 综合五月婷婷 | 色天天天| 一区二区三区在线观看免费视频 | 亚洲欧美综合 | av一级片 | 久久伊人八月婷婷综合激情 | 色综合久久88色综合天天 | 福利电影久久 | 日韩色高清 | 成av人电影 | 免费高清男女打扑克视频 | 亚洲高清精品在线 | mm1313亚洲精品国产 | 日日操日日干 | 亚洲最大成人免费网站 | 日韩福利在线观看 | 激情视频一区二区 | 91av电影网| 天天av资源 | 免费99精品国产自在在线 | 国产精品99久久久久久久久 | 日韩色综合网 | 美女视频黄免费的久久 | 在线观看蜜桃视频 | 国产99精品在线观看 | 色噜噜在线观看 | 久久99精品久久久久久久久久久久 | 丁香九月激情综合 | 国产日韩欧美综合在线 | 99久久精品国产网站 | 成 人 黄 色 视频 免费观看 | 日韩系列在线 | 日韩美女高潮 | 国产高清在线看 | 亚洲综合色网站 | 349k.cc看片app | 欧美日韩成人 | 日韩伦理片一区二区三区 | 91高清视频在线 | 人人插人人做 | 九色精品免费永久在线 | 视频精品一区二区三区 | 国产日韩欧美在线播放 | 成年人免费av网站 | 久久人人爽人人爽人人 | 久久综合九色综合久99 | 91人人爽久久涩噜噜噜 | 久久成人高清 | 亚洲最新av在线网址 | 日韩av不卡在线观看 | 激情黄色av| 午夜婷婷综合 | 欧美最猛性xxxxx亚洲精品 | 黄色亚洲大片免费在线观看 | 欧美日韩在线精品 | 国产精品久久久久aaaa | 久久久www成人免费精品 | 国产精品免费观看在线 | 亚洲国产成人精品在线 | 久久精品99国产精品日本 | 狠狠色丁香婷婷 | 在线观看视频91 | 日韩精品一区在线播放 | 久久精品视频国产 | 久久午夜羞羞影院 | 成人精品在线 | 在线激情av电影 | 国产日韩在线观看一区 | 黄a在线 | 超碰在线最新地址 | 99精品偷拍视频一区二区三区 | 91av视频| 久久久片 | 狠色在线 | 六月婷婷色| 亚洲黄在线观看 | 日韩欧美在线中文字幕 | 久草在线免费资源 | 亚洲手机天堂 | 亚洲精品国产精品乱码在线观看 | 天天插日日操 | 青春草视频在线播放 | 天天天色综合 | 三级视频国产 | 看毛片的网址 | 在线成人免费av | 亚洲成人精品在线 | 午夜影视剧场 | 色综合久久综合中文综合网 | 91久久久久久久一区二区 | 欧美一级大片在线观看 | 亚洲欧美成人综合 | 国产精品一区二区无线 | 毛片永久新网址首页 | 最新国产在线 | 伊人色综合久久天天网 | 精品a视频 | 五月天伊人网 | 国产精品第二页 | 日本久久久久久久久久 | 久久精品综合网 | 91系列在线观看 | 一区三区在线欧 | 国产一级片观看 | 午夜精品一区二区三区四区 | 日本字幕网 | 精品亚洲欧美无人区乱码 | 九热精品 | 国产99中文字幕 | 日韩av电影一区 | 成人cosplay福利网站 | 午夜av网站 | 欧美激情精品久久久 | 精品毛片一区二区免费看 | www.少妇 | 欧美成人手机版 | 欧美激情综合五月 | 日韩成年视频 | 国产一二三在线视频 | 9999国产精品 | 99视频一区二区 | 色99中文字幕 | 国产一区91| 免费高清男女打扑克视频 | 亚洲国产理论片 | 黄色小视频在线观看免费 | 亚洲综合情| 色网免费观看 | 久久只精品99品免费久23小说 | 超碰在线9 | 色综合天天在线 | 九九九热精品免费视频观看网站 | 97热久久免费频精品99 | 天天撸夜夜操 | 天天操天天干天天爱 | 国产日韩精品在线观看 | 国产操在线 | 特级毛片aaa | 亚洲最新精品 | 91精品视频免费在线观看 | 91丨九色丨丝袜 | 婷婷六月在线 | 成人影视免费看 | 国产精品情侣视频 | 特级a毛片 | 黄色的网站免费看 | 欧美日本不卡视频 | 亚洲另类视频在线观看 | 国产美女搞久久 | 99久热精品 | 欧美成人中文字幕 | 国产精品av免费在线观看 | 亚洲日韩欧美一区二区在线 | 人人狠狠综合久久亚洲 | 国产专区在线视频 | 久久99精品国产麻豆婷婷 | 免费观看国产视频 | 2019精品手机国产品在线 |