精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

探究 LayoutInflater 源碼布局解析原理

開發(fā) 前端
LayoutInflater 的作用就是將XML布局文件實例化為相應(yīng)的 View 對象,需要通過Activity.getLayoutInflater() 或 Context.getSystemService(Class) 來獲取與當(dāng)前Context已經(jīng)關(guān)聯(lián)且正確配置的標(biāo)準(zhǔn)LayoutInflater.

[[431614]]

本文轉(zhuǎn)載自微信公眾號「Android開發(fā)編程」,作者Android開發(fā)編程。轉(zhuǎn)載本文請聯(lián)系A(chǔ)ndroid開發(fā)編程公眾號。

前言

在開發(fā)中,對于 LayoutInflater 的 inflate() 方法,它的作用是把 xml 布局轉(zhuǎn)換為對應(yīng)的 View 對象,我們幾乎天天在用;

今天我們就來分析講解下;

一、什么是LayoutInflater?

LayoutInflater 的作用就是將XML布局文件實例化為相應(yīng)的 View 對象,需要通過Activity.getLayoutInflater() 或 Context.getSystemService(Class) 來獲取與當(dāng)前Context已經(jīng)關(guān)聯(lián)且正確配置的標(biāo)準(zhǔn)LayoutInflater;

  1. @SystemService(Context.LAYOUT_INFLATER_SERVICE) 
  2. public abstract class LayoutInflater { 
  3.     ... 

獲取LayoutInflater

1、 View.inflate(...)

  1. public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) { 
  2.     LayoutInflater factory = LayoutInflater.from(context); 
  3.     return factory.inflate(resource, root); 

2、Activity#getLayoutInflater()

  1. Activity.class的源代碼: 
  2. public class Activity extends .......  { 
  3. ......... 
  4.  @NonNull 
  5.     public LayoutInflater getLayoutInflater() { 
  6.         return getWindow().getLayoutInflater(); 
  7.     } 
  8. ......... 
  9.  @NonNull 
  10.     public LayoutInflater getLayoutInflater() { 
  11.         return getWindow().getLayoutInflater(); 
  12.     } 
  13. ......... 
  14.    final void attach(.....){ 
  15.           ...... 
  16.            mWindow = new PhoneWindow(this, window, activityConfigCallback); 
  17.           ....... 
  18.     } 
  19. ......... 
  20. PhoneWindow源碼: 
  21.    public PhoneWindow(Context context) { 
  22.         super(context); 
  23.         mLayoutInflater = LayoutInflater.from(context); 
  24.     } 

3、PhoneWindow#getLayoutInflater()

  1. private LayoutInflater mLayoutInflater; 
  2. public PhoneWindow(Context context) { 
  3.     super(context); 
  4.     mLayoutInflater = LayoutInflater.from(context); 
  5. public LayoutInflater getLayoutInflater() { 
  6.     return mLayoutInflater; 

4、LayoutInflater#from(Context)

  1. @SystemService(Context.LAYOUT_INFLATER_SERVICE) 
  2. public abstract class LayoutInflater { 
  3.  ..... 
  4.  /** 
  5.      * Obtains the LayoutInflater from the given context. 
  6.      */ 
  7.     public static LayoutInflater from(Context context) { 
  8.         LayoutInflater LayoutInflater = 
  9.                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
  10.         if (LayoutInflater == null) { 
  11.             throw new AssertionError("LayoutInflater not found."); 
  12.         } 
  13.         return LayoutInflater; 
  14.     } 
  15. ..... 

二、源碼分析

1、LayoutInflater#inflate(...)

調(diào)用inflate()進(jìn)行布局解析

  1. public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) { 
  2.     final Resources res = getContext().getResources(); 
  3.     1. 解析預(yù)編譯的布局 
  4.     View view = tryInflatePrecompiled(resource, res, root, attachToRoot); 
  5.     if (view != null) { 
  6.         return view
  7.     } 
  8.     2. 構(gòu)造 XmlPull 解析器  
  9.     XmlResourceParser parser = res.getLayout(resource); 
  10.     try { 
  11.     3. 執(zhí)行解析 
  12.         return inflate(parser, root, attachToRoot); 
  13.     } finally { 
  14.         parser.close(); 
  15.     } 
  • tryInflatePrecompiled(...)是解析預(yù)編譯的布局;
  • 構(gòu)造 XmlPull 解析器 XmlResourceParser
  • 執(zhí)行解析,是解析的主流程

2、inflate

  1. public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) { 
  2.     1. 結(jié)果變量 
  3.     View result = root; 
  4.     2. 最外層的標(biāo)簽 
  5.     final String name = parser.getName(); 
  6.     3. <merge> 
  7.     if (TAG_MERGE.equals(name)) { 
  8.         3.1 異常 
  9.         if (root == null || !attachToRoot) { 
  10.             throw new InflateException("<merge /> can be used only with a valid " 
  11.                 + "ViewGroup root and attachToRoot=true"); 
  12.         } 
  13.         3.2 遞歸執(zhí)行解析 
  14.         rInflate(parser, root, inflaterContext, attrs, false); 
  15.     } else { 
  16.         4.1 創(chuàng)建最外層 View 
  17.         final View temp = createViewFromTag(root, name, inflaterContext, attrs); 
  18.         ViewGroup.LayoutParams params = null
  19.         if (root != null) { 
  20.             4.2 創(chuàng)建匹配的 LayoutParams 
  21.             params = root.generateLayoutParams(attrs); 
  22.             if (!attachToRoot) { 
  23.                 4.3 如果 attachToRoot 為 false,設(shè)置LayoutParams 
  24.                 temp.setLayoutParams(params); 
  25.             } 
  26.         } 
  27.         5. 以 temp 為 root,遞歸執(zhí)行解析 
  28.         rInflateChildren(parser, temp, attrs, true); 
  29.         6. attachToRoot 為 true,addView() 
  30.         if (root != null && attachToRoot) { 
  31.             root.addView(temp, params); 
  32.         } 
  33.         7. root 為空 或者 attachToRoot 為 false,返回 temp 
  34.         if (root == null || !attachToRoot) { 
  35.             result = temp
  36.         } 
  37.     } 
  38.     return result; 
  39. -> 3.2 
  40. void rInflate(XmlPullParser parser, View parent, Context context, AttributeSet attrs, boolean finishInflate) { 
  41.     while(parser 未結(jié)束) { 
  42.         if (TAG_INCLUDE.equals(name)) { 
  43.             1) <include> 
  44.             if (parser.getDepth() == 0) { 
  45.                 throw new InflateException("<include /> cannot be the root element"); 
  46.             } 
  47.             parseInclude(parser, context, parent, attrs); 
  48.         } else if (TAG_MERGE.equals(name)) { 
  49.             2) <merge> 
  50.             throw new InflateException("<merge /> must be the root element"); 
  51.         } else { 
  52.             3) 創(chuàng)建 View  
  53.             final View view = createViewFromTag(parent, name, context, attrs); 
  54.             final ViewGroup viewGroup = (ViewGroup) parent; 
  55.             final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); 
  56.             4) 遞歸 
  57.             rInflateChildren(parser, view, attrs, true); 
  58.             5) 添加到視圖樹 
  59.             viewGroup.addView(view, params); 
  60.         } 
  61.     } 
  62. -> 5. 遞歸執(zhí)行解析 
  63. final void rInflateChildren(XmlPullParser parser, View parent, AttributeSet attrs, 
  64.             boolean finishInflate) throws XmlPullParserException, IOException { 
  65.     rInflate(parser, parent, parent.getContext(), attrs, finishInflate); 
  66. 3、createViewFromTag 
  67. createViewFromTag(),它負(fù)責(zé)由 <tag> 創(chuàng)建 View 對象 
  68.     View createViewFromTag(View parent, String name, Context context, AttributeSet attrs, 
  69.             boolean ignoreThemeAttr) { 
  70.         if (name.equals("view")) { 
  71.             name = attrs.getAttributeValue(null"class"); 
  72.         } 
  73.         // Apply a theme wrapper, if allowed and one is specified. 
  74.         if (!ignoreThemeAttr) { 
  75.             final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME); 
  76.             final int themeResId = ta.getResourceId(0, 0); 
  77.             if (themeResId != 0) { 
  78.                 context = new ContextThemeWrapper(context, themeResId); 
  79.             } 
  80.             ta.recycle(); 
  81.         } 
  82.         if (name.equals(TAG_1995)) { 
  83.             // Let's party like it's 1995! 
  84.             return new BlinkLayout(context, attrs); 
  85.         } 
  86.         try { 
  87.             View view
  88.             if (mFactory2 != null) { 
  89.                 // ① 有mFactory2,則調(diào)用mFactory2的onCreateView方法 
  90.                 view = mFactory2.onCreateView(parent, name, context, attrs); 
  91.             } else if (mFactory != null) { 
  92.                 // ② 有mFactory,則調(diào)用mFactory的onCreateView方法 
  93.                 view = mFactory.onCreateView(name, context, attrs); 
  94.             } else { 
  95.                 view = null
  96.             } 
  97.             if (view == null && mPrivateFactory != null) { 
  98.                 // ③ 有mPrivateFactory,則調(diào)用mPrivateFactory的onCreateView方法 
  99.                 view = mPrivateFactory.onCreateView(parent, name, context, attrs); 
  100.             } 
  101.             if (view == null) { 
  102.                 // ④ 走到這步說明三個Factory都沒有,則開始自己創(chuàng)建View 
  103.                 final Object lastContext = mConstructorArgs[0]; 
  104.                 mConstructorArgs[0] = context; 
  105.                 try { 
  106.                     if (-1 == name.indexOf('.')) { 
  107.                         // ⑤ 如果Viewname中不包含 '.' 則說明是系統(tǒng)控件,會在接下來的調(diào)用鏈在name前面加上 'android.view.' 
  108.                         view = onCreateView(parent, name, attrs); 
  109.                     } else { 
  110.                         // ⑥ 如果name中包含 '.' 則直接調(diào)用createView方法,onCreateView 后續(xù)也是調(diào)用了createView 
  111.                         view = createView(namenull, attrs); 
  112.                     } 
  113.                 } finally { 
  114.                     mConstructorArgs[0] = lastContext; 
  115.                 } 
  116.             } 
  117.             return view
  118.         } catch (InflateException e) { 
  119.             throw e; 
  120.         }  
  121.     } 
  • createViewFromTag 方法比較簡單,首先嘗試通過 Factory 來創(chuàng)建View;
  • 如果沒有 Factory 的話則通過 createView 來創(chuàng)建View;

3、createView 方法解析

  1. public final View createView(String name, String prefix, AttributeSet attrs) 
  2.             throws ClassNotFoundException, InflateException { 
  3.         Constructor<? extends View> constructor = sConstructorMap.get(name); 
  4.         if (constructor != null && !verifyClassLoader(constructor)) { 
  5.             constructor = null
  6.             sConstructorMap.remove(name); 
  7.         } 
  8.         Class<? extends View> clazz = null
  9.         try { 
  10.             Trace.traceBegin(Trace.TRACE_TAG_VIEW, name); 
  11.             if (constructor == null) { 
  12.                 // Class not found in the cache, see if it's realand try to add it 
  13.                 clazz = mContext.getClassLoader().loadClass( 
  14.                         prefix != null ? (prefix + name) : name).asSubclass(View.class); 
  15.                 if (mFilter != null && clazz != null) { 
  16.                     boolean allowed = mFilter.onLoadClass(clazz); 
  17.                     if (!allowed) { 
  18.                         failNotAllowed(name, prefix, attrs); 
  19.                     } 
  20.                 } 
  21.                 // ① 反射獲取這個View的構(gòu)造器 
  22.                 constructor = clazz.getConstructor(mConstructorSignature); 
  23.                 constructor.setAccessible(true); 
  24.                 // ② 緩存構(gòu)造器 
  25.                 sConstructorMap.put(name, constructor); 
  26.             } else { 
  27.                 // If we have a filter, apply it to cached constructor 
  28.                 if (mFilter != null) { 
  29.                     // Have we seen this name before? 
  30.                     Boolean allowedState = mFilterMap.get(name); 
  31.                     if (allowedState == null) { 
  32.                         // New class -- remember whether it is allowed 
  33.                         clazz = mContext.getClassLoader().loadClass( 
  34.                                 prefix != null ? (prefix + name) : name).asSubclass(View.class); 
  35.                         boolean allowed = clazz != null && mFilter.onLoadClass(clazz); 
  36.                         mFilterMap.put(name, allowed); 
  37.                         if (!allowed) { 
  38.                             failNotAllowed(name, prefix, attrs); 
  39.                         } 
  40.                     } else if (allowedState.equals(Boolean.FALSE)) { 
  41.                         failNotAllowed(name, prefix, attrs); 
  42.                     } 
  43.                 } 
  44.             } 
  45.             Object lastContext = mConstructorArgs[0]; 
  46.             if (mConstructorArgs[0] == null) { 
  47.                 // Fill in the context if not already within inflation. 
  48.                 mConstructorArgs[0] = mContext; 
  49.             } 
  50.             Object[] args = mConstructorArgs; 
  51.             args[1] = attrs; 
  52.             // ③ 使用反射創(chuàng)建 View 對象,這樣一個 View 就被創(chuàng)建出來了 
  53.             final View view = constructor.newInstance(args); 
  54.             if (view instanceof ViewStub) { 
  55.                 // Use the same context when inflating ViewStub later. 
  56.                 final ViewStub viewStub = (ViewStub) view
  57.                 viewStub.setLayoutInflater(cloneInContext((Context) args[0])); 
  58.             } 
  59.             mConstructorArgs[0] = lastContext; 
  60.             return view
  61.         } catch (ClassCastException e) { 
  62.         }  
  63.     } 

createView 方法也比較簡單,通過反射來創(chuàng)建的 View 對象;

4、 Factory2 接口

Factory2可以攔截實例化 View 的步驟,在 LayoutInflater 中有兩個方法可以設(shè)置:

  1. 方法1: 
  2. public void setFactory2(Factory2 factory) { 
  3.     if (mFactorySet) { 
  4.         關(guān)注點:禁止重復(fù)設(shè)置 
  5.         throw new IllegalStateException("A factory has already been set on this LayoutInflater"); 
  6.     } 
  7.     if (factory == null) { 
  8.         throw new NullPointerException("Given factory can not be null"); 
  9.     } 
  10.     mFactorySet = true
  11.     if (mFactory == null) { 
  12.         mFactory = mFactory2 = factory; 
  13.     } else { 
  14.         mFactory = mFactory2 = new FactoryMerger(factory, factory, mFactory, mFactory2); 
  15.     } 
  1. 方法2 @hide 
  2. public void setPrivateFactory(Factory2 factory) { 
  3.     if (mPrivateFactory == null) { 
  4.         mPrivateFactory = factory; 
  5.     } else { 
  6.         mPrivateFactory = new FactoryMerger(factory, factory, mPrivateFactory, mPrivateFactory); 
  7.     } 

使用 setFactory2() 和 setPrivateFactory() 可以設(shè)置 Factory2 接口(攔截器),其中同一個 LayoutInflater 的setFactory2()不能重復(fù)設(shè)置,setPrivateFactory() 是 hide 方法;

總結(jié)

  • 通過 XML 的 Pull 解析方式獲取 View 的標(biāo)簽;
  • 通過標(biāo)簽以反射的方式來創(chuàng)建 View 對象;
  • 如果是 ViewGroup 的話則會對子 View 遍歷并重復(fù)以上步驟,然后 add 到父 View 中;
  • 與之相關(guān)的幾個方法:inflate ——》 rInflate ——》 createViewFromTag ——》 createView ;
  • Factory2 是一個很實用的接口,需要掌握通過 setFactory2() 攔截布局解析的技巧;

 

責(zé)任編輯:武曉燕 來源: Android開發(fā)編程
相關(guān)推薦

2024-05-07 08:28:06

XML代碼Java

2024-01-18 08:31:22

go實現(xiàn)gorm框架

2025-02-06 08:24:25

AQS開發(fā)Java

2017-05-18 15:02:36

AndroidGC原理JVM內(nèi)存回收

2022-12-09 08:10:12

kubectl容器源碼

2021-09-09 06:55:43

AndroidViewDragHel原理

2024-09-04 11:42:17

Vue3.5源碼API

2020-10-10 08:20:27

Spring Boot運行原理代碼

2023-08-31 08:12:23

應(yīng)用場景業(yè)務(wù)異常HTTP

2010-09-16 14:42:44

JVM

2014-04-02 17:10:00

虛擬應(yīng)用工作原理

2019-01-10 08:24:06

2010-08-24 09:05:20

CSS+DIV

2021-08-27 07:47:07

Nacos灰度源碼

2015-10-10 09:39:42

Java線程池源碼解析

2013-06-08 10:11:31

Java線程池架構(gòu)

2010-09-15 14:00:06

position屬性DIV

2012-05-03 08:27:20

Linux進(jìn)程

2025-04-11 09:57:16

2021-05-26 11:30:24

Java線程池代碼
點贊
收藏

51CTO技術(shù)棧公眾號

久久久久久久黄色片| 国产福利在线观看视频| 国内精品久久久久久野外| 国产精品123| 日韩av不卡在线| 午夜精品福利在线视频| 日韩极品少妇| 宅男噜噜噜66一区二区66| 欧美性受xxxx黑人猛交| 手机看片福利视频| 亚洲精品不卡在线观看| 一本色道a无线码一区v| 久久观看最新视频| 黄上黄在线观看| 国产成人aaa| 国产精品流白浆视频| 国产大片中文字幕在线观看| 日本不卡二三区| 亚洲第一区在线观看| 无限资源日本好片| 日韩精品极品| 一区二区三区在线观看视频| 日韩精品伦理第一区| 后入内射欧美99二区视频| 毛片基地黄久久久久久天堂| 欧美在线观看一区二区三区| 国产性xxxx| 日韩av久操| 亚洲欧美日韩天堂| 大桥未久恸哭の女教师| 99精品国产九九国产精品| 色综合 综合色| 无码专区aaaaaa免费视频| 大地资源网3页在线观看| 日本一二三四高清不卡| 欧洲精品码一区二区三区免费看| 黑人精品一区二区三区| 国产综合色视频| 国产精品嫩草视频| 无码视频一区二区三区| 亚洲一区二区三区免费在线观看| 欧美黄色性视频| 国产福利视频网站| 国产精品久久久久无码av| 国产亚洲精品高潮| 人人妻人人藻人人爽欧美一区| 久久1电影院| 91精品国产综合久久精品麻豆| 亚洲视频第二页| www.国产精品| 欧美日韩一卡二卡三卡| 自拍偷拍一区二区三区四区| 巨胸喷奶水www久久久| 欧美影视一区二区三区| 尤蜜粉嫩av国产一区二区三区| 成人性生活视频| 一本色道久久加勒比精品| 国产欧美在线一区| 欧美大片免费观看网址| 色狠狠综合天天综合综合| 精品国产成人av在线免| 欧美影视资讯| 欧美精品自拍偷拍| 中文字幕avav| 粉嫩久久久久久久极品| 亚洲丁香婷深爱综合| www.超碰97| 蜜桃精品wwwmitaows| 国产午夜精品视频免费不卡69堂| 亚洲精品国产91| 精品一二三区| 精品国产一区二区三区久久狼5月| 91香蕉一区二区三区在线观看| 欧美黄色一区| 97久久伊人激情网| 日本黄色中文字幕| 激情成人综合网| 国产66精品久久久久999小说| 日韩在线观看视频网站| 久久亚洲捆绑美女| 亚洲欧美影院| 久久一卡二卡| 欧美怡红院视频| 丰满人妻一区二区三区大胸| 亚洲国产欧美日韩在线观看第一区 | 亚洲国产精品一区在线观看不卡| 日本电影全部在线观看网站视频| 亚洲最新视频在线观看| 男女午夜激情视频| 99re8精品视频在线观看| 亚洲国语精品自产拍在线观看| 欧美成人国产精品一区二区| 影音先锋日韩在线| 欧美在线视频免费播放| 国产免费黄色网址| 99精品一区二区| 中文视频一区视频二区视频三区| 欧美理论电影| 欧美日韩一区二区欧美激情| 喷水视频在线观看| 亚洲电影影音先锋| 日本久久亚洲电影| а√中文在线资源库| 欧美极品少妇xxxxⅹ高跟鞋| 日韩成人三级视频| 国产精品久久久久77777丨| 精品国产乱码久久久久久免费 | 五月激情六月婷婷| 中文字幕在线视频一区| 日本精品一区在线观看| 国产在线不卡一区二区三区| 国产一区二区三区在线视频 | 久热国产在线| 色视频欧美一区二区三区| 欧美一级大片免费看| 欧美亚洲精品在线| 欧美亚洲伦理www| 亚洲国产精品久久人人爱潘金莲| 日本一二三不卡| 国产精品无码av在线播放| 激情视频亚洲| 在线看日韩av| 色av性av丰满av| av爱爱亚洲一区| 女人床在线观看| 日韩五码电影| 中文字幕av一区中文字幕天堂| 国产超碰人人爽人人做人人爱| 国产伦精一区二区三区| 中文字幕精品—区二区日日骚| 成人爱爱网址| 日韩国产在线看| 天海翼一区二区| 成人综合在线视频| 波多野结衣与黑人| 国产高清精品二区| 精品国产一区二区三区久久狼黑人| 亚洲欧美另类在线视频| 91日韩精品一区| 黄色片网址在线观看| youjizz亚洲| 久久久久久久电影一区| 亚洲伦理在线观看| 亚洲一区在线视频观看| 国产成人精品一区二区三区在线观看| 婷婷久久一区| 91免费欧美精品| 91一区二区三区在线| 欧美一区二区视频观看视频| 久久久久久视频| 国产精品亚洲午夜一区二区三区| 无码毛片aaa在线| 国产精品成人3p一区二区三区| 日韩中文字幕在线免费观看| 91久久精品无码一区二区| 国产精品每日更新| 污网站在线免费| 亚洲激情中文在线| 丁香婷婷久久久综合精品国产| 色女人在线视频| 亚洲国产精品系列| 久久精品视频7| 欧美国产激情二区三区 | 涩涩涩久久久成人精品| 精品国模在线视频| 国产三级午夜理伦三级| 亚洲综合色婷婷| 91精品久久久久久久久久| 日日摸日日碰夜夜爽无码| 日本综合字幕| 在线观看精品自拍私拍| 在线观看国产小视频| 亚洲欧美另类小说| yy1111111| 日产欧产美韩系列久久99| 中文字幕一区二区三区有限公司 | 久久国产精品色婷婷| 伊人网在线免费| 无码少妇一区二区三区| 国产精品亚洲精品| 欧美人体视频xxxxx| 亚洲欧美国产va在线影院| 一级黄色片在线| 无码av免费一区二区三区试看| 欧美多人猛交狂配| 极品销魂美女一区二区三区| 国产无限制自拍| 精品久久久久久久久久久下田| 91九色综合久久| 在线免费看h| www.日本久久久久com.| 蜜臀久久99精品久久久| 欧美在线免费视屏| 久久网一区二区| 国产精品每日更新在线播放网址| 日韩成人av影院| 免费高清不卡av| 国产 日韩 欧美在线| 波多野结衣一区| 国产精品污www一区二区三区| 国产成人毛片| 9.1国产丝袜在线观看 | 日韩在线欧美| 九色一区二区| 日本在线成人| 国产精品久久久久久久午夜| 国产嫩草在线视频| 日韩在线国产精品| 日本成人一区二区三区| 欧美一区二区三区视频免费| 亚洲精品国产无码| 亚洲成人免费看| 婷婷久久综合网| 国产视频911| 成人无码www在线看免费| 国模少妇一区二区三区 | 国产老妇另类xxxxx| 欧美激情精品久久久久久小说| 黄色av一区| 免费成人深夜夜行网站视频| 精品久久不卡| 欧美成熟毛茸茸复古| 99精品国产一区二区三区2021 | 91成人精品在线| 国产又爽又黄的激情精品视频| 大胆人体一区二区| 88国产精品欧美一区二区三区| 污网站在线免费看| 另类天堂视频在线观看| 日本在线播放| 色综合亚洲精品激情狠狠| 牛牛影视精品影视| 日韩精品电影网| 午夜视频免费看| 亚洲护士老师的毛茸茸最新章节| 亚洲国产精品二区| 精品国产在天天线2019| 粉嫩av一区二区夜夜嗨| 精品少妇一区二区三区免费观看 | 粉嫩蜜臀av国产精品网站| 一起草最新网址| 国产精品一区在线观看你懂的| 黄大色黄女片18第一次| 麻豆精品视频在线观看| 免费成年人高清视频| 精品综合免费视频观看| 91 视频免费观看| 国产麻豆欧美日韩一区| 中文字幕欧美视频| 国产福利电影一区二区三区| 巨乳女教师的诱惑| 国产精品亚洲综合一区在线观看| 久久久久久无码精品人妻一区二区| 国产乱人伦精品一区二区在线观看| 色黄视频免费看| 国产盗摄视频一区二区三区| 欧美图片自拍偷拍| jvid福利写真一区二区三区| 日本一区二区三区网站| 久久久99久久| 国产欧美小视频| 综合色中文字幕| 国产在线视频99| 黑人欧美xxxx| 在线免费观看中文字幕| 5月丁香婷婷综合| 亚洲爱情岛论坛永久| 亚洲精品久久在线| 福利视频在线播放| 久久国产精品电影| 国产乱码在线| 国产成人一区三区| 宅男噜噜噜66国产精品免费| 99久热re在线精品996热视频| 久久动漫网址| 亚洲a∨一区二区三区| 久久久久久久久丰满| 丰满少妇大力进入| 日韩精品一区第一页| 亚洲制服在线观看| 91在线视频官网| 后入内射无码人妻一区| 亚洲福利电影网| 中文字幕你懂的| 日韩精品一区在线| 国产在线一二三区| 欧美精品一区三区| 色香欲www7777综合网| 91嫩草在线| 国产一区二区三区四区五区传媒 | 91麻豆精品久久毛片一级| 一区二区三区欧美亚洲| 午夜精品久久久久久久蜜桃| 欧美一级二级在线观看| 国产人成在线视频| 久久久久久久国产| 只有精品亚洲| 日本日本精品二区免费| 欧美日本亚洲韩国国产| av网站在线不卡| 91视频在线观看免费| 日韩黄色免费观看| 欧美亚洲动漫另类| 无码国产精品高潮久久99| 久久久国产视频| 亚洲四虎影院| 免费观看成人在线| 国一区二区在线观看| 日韩av.com| 国产亚洲欧洲一区高清在线观看| 国产一级中文字幕| 日韩一二三区视频| 在线观看免费网站黄| 国产91热爆ts人妖在线| 好吊妞视频这里有精品| 裸体裸乳免费看| 久久精品国产一区二区三| 玖玖爱在线观看| 精品福利在线看| 亚洲乱熟女一区二区| 欧美成人激情视频免费观看| 国产亚洲人成a在线v网站| 欧美一区二区视频在线| 一本综合精品| 中国一级特黄录像播放| 一区二区三区中文字幕精品精品 | 亚洲黄一区二区| 日本在线观看大片免费视频| 成人国产精品久久久| 欧美电影免费播放| av无码精品一区二区三区| 26uuu亚洲| 性无码专区无码| 日韩av在线天堂网| 免费毛片b在线观看| 精品在线不卡| 国产精品日本| 搡老熟女老女人一区二区| 婷婷综合五月天| 亚洲色欧美另类| 26uuu另类亚洲欧美日本老年| 国偷自产视频一区二区久| www.国产在线播放| 不卡电影一区二区三区| 国产性xxxx高清| 国产视频在线观看一区二区| 亚洲人成午夜免电影费观看| 久久久久久精| 免费日韩av片| 怡红院一区二区三区| 欧美人牲a欧美精品| av网址在线看| 99re在线观看视频| 日韩一级不卡| 3d动漫精品啪啪一区二区下载| 91福利区一区二区三区| 91伦理视频在线观看| 国产一区香蕉久久| 欧美黄在线观看| 国产激情第一页| 色屁屁一区二区| 五月香视频在线观看| 亚洲综合小说区| 亚洲国产影院| 色婷婷在线影院| 欧美精品亚洲一区二区在线播放| 中中文字幕av在线| 精品国产一区二区三区免费| 首页欧美精品中文字幕| 欧美一级特黄高清视频| 亚洲精品在线观看网站| 日韩电影av| 精品国产无码在线| www.一区二区| 在线视频 91| 欧美国产第一页| 精品国产欧美日韩| 色偷偷中文字幕| 丁香五六月婷婷久久激情| aaa在线免费观看| 国产高清一区二区三区| 久久久久一区| 久草综合在线视频| 日韩精品视频免费| 成人豆花视频| 97成人在线观看视频| 国产精品久久久久久久午夜片| 丰满少妇在线观看bd| 国产精品久久久久91| 欧美日韩少妇| 中文字幕成人动漫| 欧美成人午夜电影| 国产麻豆久久| 成品人视频ww入口| 国产精品免费看片| 色综合久久久久久| 91久久精品一区| 欧美一级播放| 国产小视频在线观看免费| 在线观看精品国产视频|