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

Android如何編寫基于編譯時注解的項目

移動開發(fā) Android
本文將以編寫一個View注入的框架為線索,詳細介紹編寫此類框架的步驟。

一、概述

在Android應用開發(fā)中,我們常常為了提升開發(fā)效率會選擇使用一些基于注解的框架,但是由于反射造成一定運行效率的損耗,所以我們會更青睞于編譯時注解的框架,例如:

  • butterknife免去我們編寫View的初始化以及事件的注入的代碼。
  • EventBus3方便我們實現(xiàn)組建間通訊。
  • fragmentargs輕松的為fragment添加參數(shù)信息,并提供創(chuàng)建方法。
  • ParcelableGenerator可實現(xiàn)自動將任意對象轉換為Parcelable類型,方便對象傳輸。

類似的庫還有非常多,大多這些的庫都是為了自動幫我們完成日常編碼中需要重復編寫的部分(例如:每個Activity中的View都需要初始化,每個實現(xiàn)Parcelable接口的對象都需要編寫很多固定寫法的代碼)。

[[192267]]

這里并不是說上述框架就一定沒有使用反射了,其實上述其中部分框架內(nèi)部還是有部分實現(xiàn)是依賴于反射的,但是很少而且一般都做了緩存的處理,所以相對來說,效率影響很小。

但是在使用這類項目的時候,有時候出現(xiàn)錯誤會難以調(diào)試,主要原因還是很多用戶并不了解這類框架其內(nèi)部的原理,所以遇到問題時會消耗大量的時間去排查。

那么,于情于理,在編譯時注解框架這么火的時刻,我們有理由去學習:如何編寫一個機遇編譯時注解的項目

首先,是為了了解其原理,這樣在我們使用類似框架遇到問題的時候,能夠找到正確的途徑去排查問題;其次,我們?nèi)绻泻玫南敕ǎl(fā)現(xiàn)某些代碼需要重復創(chuàng)建,我們也可以自己來寫個框架方便自己日常的編碼,提升編碼效率;***也算是自身技術的提升。

注:以下使用IDE為Android Studio.

本文將以編寫一個View注入的框架為線索,詳細介紹編寫此類框架的步驟。

二、編寫前的準備

在編寫此類框架的時候,一般需要建立多個module,例如本文即將實現(xiàn)的例子:

  • ioc-annotation 用于存放注解等,Java模塊
  • ioc-compiler 用于編寫注解處理器,Java模塊
  • ioc-api 用于給用戶提供使用的API,本例為Andriod模塊
  • ioc-sample 示例,本例為Andriod模塊

那么除了示例以為,一般要建立3個module,module的名字你可以自己考慮,上述給出了一個簡單的參考。當然如果條件允許的話,有的開發(fā)者喜歡將存放注解和API這兩個module合并為一個module。

對于module間的依賴,因為編寫注解處理器需要依賴相關注解,所以:

  • ioc-compiler依賴ioc-annotation

我們在使用的過程中,會用到注解以及相關API

  • 所以ioc-sample依賴ioc-api;ioc-api依賴ioc-annotation

三、注解模塊的實現(xiàn)

注解模塊,主要用于存放一些注解類,本例是模板butterknife實現(xiàn)View注入,所以本例只需要一個注解類:

 

  1. @Retention(RetentionPolicy.CLASS) 
  2. @Target(ElementType.FIELD) 
  3. public @interface BindView 
  4.     int value(); 

我們設置的保留策略為Class,注解用于Field上。這里我們需要在使用時傳入一個id,直接以value的形式進行設置即可。

你在編寫的時候,分析自己需要幾個注解類,并且正確的設置@Target以及@Retention即可。

四、注解處理器的實現(xiàn)

定義完成注解后,就可以去編寫注解處理器了,這塊有點復雜,但是也算是有章可循的。

該模塊,我們一般會依賴注解模塊,以及可以使用一個auto-service庫

build.gradle的依賴情況如下:

 

  1. dependencies { 
  2.     compile 'com.google.auto.service:auto-service:1.0-rc2' 
  3.     compile project (':ioc-annotation'

auto-service庫可以幫我們?nèi)ド蒑ETA-INF等信息。

(1)基本代碼

注解處理器一般繼承于AbstractProcessor,剛才我們說有章可循,是因為部分代碼的寫法基本是固定的,如下:

 

  1. @AutoService(Processor.class) 
  2. public class IocProcessor extends AbstractProcessor{ 
  3.     private Filer mFileUtils; 
  4.     private Elements mElementUtils; 
  5.     private Messager mMessager; 
  6.     @Override 
  7.     public synchronized void init(ProcessingEnvironment processingEnv){ 
  8.         super.init(processingEnv); 
  9.         mFileUtils = processingEnv.getFiler(); 
  10.         mElementUtils = processingEnv.getElementUtils(); 
  11.         mMessager = processingEnv.getMessager(); 
  12.     } 
  13.     @Override 
  14.     public Set<String> getSupportedAnnotationTypes(){ 
  15.         Set<String> annotationTypes = new LinkedHashSet<String>(); 
  16.         annotationTypes.add(BindView.class.getCanonicalName()); 
  17.         return annotationTypes; 
  18.     } 
  19.     @Override 
  20.     public SourceVersion getSupportedSourceVersion(){ 
  21.         return SourceVersion.latestSupported(); 
  22.     } 
  23.     @Override 
  24.     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){ 
  25.     } 

在實現(xiàn)AbstractProcessor后,process()方法是必須實現(xiàn)的,也是我們編寫代碼的核心部分,后面會介紹。

我們一般會實現(xiàn)getSupportedAnnotationTypes()和getSupportedSourceVersion()兩個方法,這兩個方法一個返回支持的注解類型,一個返回支持的源碼版本,參考上面的代碼,寫法基本是固定的。

除此以外,我們還會選擇復寫init()方法,該方法傳入一個參數(shù)processingEnv,可以幫助我們?nèi)コ跏蓟恍└割愵悾?/p>

  • Filer mFileUtils; 跟文件相關的輔助類,生成JavaSourceCode.
  • Elements mElementUtils;跟元素相關的輔助類,幫助我們?nèi)カ@取一些元素相關的信息。
  • Messager mMessager;跟日志相關的輔助類。

這里簡單提一下Elemnet,我們簡單認識下它的幾個子類,根據(jù)下面的注釋,應該已經(jīng)有了一個簡單認知。

 

  1. Element  
  2.   - VariableElement //一般代表成員變量 
  3.   - ExecutableElement //一般代表類中的方法 
  4.   - TypeElement //一般代表代表類 
  5.   - PackageElement //一般代表Package 

(2)process的實現(xiàn)

process中的實現(xiàn),相比較會比較復雜一點,一般你可以認為兩個大步驟:

  • 收集信息
  • 生成代理類(本文把編譯時生成的類叫代理類)

什么叫收集信息呢?就是根據(jù)你的注解聲明,拿到對應的Element,然后獲取到我們所需要的信息,這個信息肯定是為了后面生成JavaFileObject所準備的。

例如本例,我們會針對每一個類生成一個代理類,例如MainActivity我們會生成一個MainActivity$$ViewInjector。那么如果多個類中聲明了注解,就對應了多個類,這里就需要:

  • 一個類對象,代表具體某個類的代理類生成的全部信息,本例中為ProxyInfo
  • 一個集合,存放上述類對象(到時候遍歷生成代理類),本例中為Map,key為類的全路徑。

這里的描述有點模糊沒關系,一會結合代碼就好理解了。

a.收集信息

 

  1. private Map<String, ProxyInfo> mProxyMap = new HashMap<String, ProxyInfo>(); 
  2. @Override 
  3. public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){ 
  4.     mProxyMap.clear(); 
  5.     Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(BindView.class); 
  6.     //一、收集信息 
  7.     for (Element element : elements){ 
  8.         //檢查element類型 
  9.         if (!checkAnnotationUseValid(element)){ 
  10.             return false
  11.         } 
  12.         //field type 
  13.         VariableElement variableElement = (VariableElement) element; 
  14.         //class type 
  15.         TypeElement typeElement = (TypeElement) variableElement.getEnclosingElement();//TypeElement 
  16.         String qualifiedName = typeElement.getQualifiedName().toString(); 
  17.  
  18.         ProxyInfo proxyInfo = mProxyMap.get(qualifiedName); 
  19.         if (proxyInfo == null){ 
  20.             proxyInfo = new ProxyInfo(mElementUtils, typeElement); 
  21.             mProxyMap.put(qualifiedName, proxyInfo); 
  22.         } 
  23.         BindView annotation = variableElement.getAnnotation(BindView.class); 
  24.         int id = annotation.value(); 
  25.         proxyInfo.mInjectElements.put(id, variableElement); 
  26.     } 
  27.     return true

首先我們調(diào)用一下mProxyMap.clear();,因為process可能會多次調(diào)用,避免生成重復的代理類,避免生成類的類名已存在異常。

然后,通過roundEnv.getElementsAnnotatedWith拿到我們通過@BindView注解的元素,這里返回值,按照我們的預期應該是VariableElement集合,因為我們用于成員變量上。

接下來for循環(huán)我們的元素,首先檢查類型是否是VariableElement.

然后拿到對應的類信息TypeElement,繼而生成ProxyInfo對象,這里通過一個mProxyMap進行檢查,key為qualifiedName即類的全路徑,如果沒有生成才會去生成一個新的,ProxyInfo與類是一一對應的。

接下來,會將與該類對應的且被@BindView聲明的VariableElement加入到ProxyInfo中去,key為我們聲明時填寫的id,即View的id。

這樣就完成了信息的收集,收集完成信息后,應該就可以去生成代理類了。

b.生成代理類

 

  1. @Override 
  2. public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv){ 
  3.     //...省略收集信息的代碼,以及try,catch相關 
  4.     for(String key : mProxyMap.keySet()){ 
  5.         ProxyInfo proxyInfo = mProxyMap.get(key); 
  6.         JavaFileObject sourceFile = mFileUtils.createSourceFile( 
  7.                 proxyInfo.getProxyClassFullName(), proxyInfo.getTypeElement()); 
  8.             Writer writer = sourceFile.openWriter(); 
  9.             writer.write(proxyInfo.generateJavaCode()); 
  10.             writer.flush(); 
  11.             writer.close(); 
  12.     } 
  13.     return true

可以看到生成代理類的代碼非常的簡短,主要就是遍歷我們的mProxyMap,然后取得每一個ProxyInfo,***通過mFileUtils.createSourceFile來創(chuàng)建文件對象,類名為proxyInfo.getProxyClassFullName(),寫入的內(nèi)容為proxyInfo.generateJavaCode().

看來生成Java代碼的方法都在ProxyInfo里面。

c.生成Java代碼

這里我們主要關注其生成Java代碼的方式。

下面主要看生成Java代碼的方法:

 

  1. #ProxyInfo 
  2. //key為id,value為對應的成員變量 
  3. public Map<Integer, VariableElement> mInjectElements = new HashMap<Integer, VariableElement>(); 
  4.  
  5. public String generateJavaCode(){ 
  6.     StringBuilder builder = new StringBuilder(); 
  7.     builder.append("package " + mPackageName).append(";\n\n"); 
  8.     builder.append("import com.zhy.ioc.*;\n"); 
  9.     builder.append("public class ").append(mProxyClassName).append(" implements " + SUFFIX + "<" + mTypeElement.getQualifiedName() + ">"); 
  10.     builder.append("\n{\n"); 
  11.     generateMethod(builder); 
  12.     builder.append("\n}\n"); 
  13.     return builder.toString(); 
  14. private void generateMethod(StringBuilder builder){ 
  15.      builder.append("public void inject("+mTypeElement.getQualifiedName()+" host , Object object )"); 
  16.     builder.append("\n{\n"); 
  17.     for(int id : mInjectElements.keySet()){ 
  18.         VariableElement variableElement = mInjectElements.get(id); 
  19.         String name = variableElement.getSimpleName().toString(); 
  20.         String type = variableElement.asType().toString() ; 
  21.  
  22.         builder.append(" if(object instanceof android.app.Activity)"); 
  23.         builder.append("\n{\n"); 
  24.         builder.append("host."+name).append(" = "); 
  25.         builder.append("("+type+")(((android.app.Activity)object).findViewById("+id+"));"); 
  26.         builder.append("\n}\n").append("else").append("\n{\n"); 
  27.         builder.append("host."+name).append(" = "); 
  28.         builder.append("("+type+")(((android.view.View)object).findViewById("+id+"));"); 
  29.         builder.append("\n}\n"); 
  30.     } 
  31.     builder.append("\n}\n"); 

這里主要就是靠收集到的信息,拼接完成的代理類對象了,看起來會比較頭疼,不過我給出一個生成后的代碼,對比著看會很多。

 

  1. package com.zhy.ioc_sample; 
  2. import com.zhy.ioc.*; 
  3. public class MainActivity$$ViewInjector implements ViewInjector<com.zhy.ioc_sample.MainActivity>{ 
  4.     @Override 
  5.     public void inject(com.zhy.sample.MainActivity host , Object object ){ 
  6.         if(object instanceof android.app.Activity){ 
  7.             host.mTv = (android.widget.TextView)(((android.app.Activity)object).findViewById(2131492945)); 
  8.         } 
  9.         else
  10.             host.mTv = (android.widget.TextView)(((android.view.View)object).findViewById(2131492945)); 
  11.         } 
  12.     } 

這樣對著上面代碼看會好很多,其實就死根據(jù)收集到的成員變量(通過@BindView聲明的),然后根據(jù)我們具體要實現(xiàn)的需求去生成java代碼。

這里注意下,生成的代碼實現(xiàn)了一個接口ViewInjector,該接口是為了統(tǒng)一所有的代理類對象的類型,到時候我們需要強轉代理類對象為該接口類型,調(diào)用其方法;接口是泛型,主要就是傳入實際類對象,例如MainActivity,因為我們在生成代理類中的代碼,實際上就是實際類.成員變量的方式進行訪問,所以,使用編譯時注解的成員變量一般都不允許private修飾符修飾(有的允許,但是需要提供getter,setter訪問方法)。

這里采用了完全拼接的方式編寫Java代碼,你也可以使用一些開源庫,來通過Java api的方式來生成代碼,例如:javapoet.

  1. A Java API for generating .java source files. 

到這里我們就完成了代理類的生成,這里任何的注解處理器的編寫方式基本都遵循著收集信息、生成代理類的步驟。

五、API模塊的實現(xiàn)

有了代理類之后,我們一般還會提供API供用戶去訪問,例如本例的訪問入口是

 

  1. //Activity中 
  2.  Ioc.inject(Activity); 
  3.  //Fragment中,獲取ViewHolder中 
  4.  Ioc.inject(this, view); 

模仿了butterknife,***個參數(shù)為宿主對象,第二個參數(shù)為實際調(diào)用findViewById的對象;當然在Actiivty中,兩個參數(shù)就一樣了。

API一般如何編寫呢?

其實很簡單,只要你了解了其原理,這個API就干兩件事:

  • 根據(jù)傳入的host尋找我們生成的代理類:例如MainActivity->MainActity$$ViewInjector。
  • 強轉為統(tǒng)一的接口,調(diào)用接口提供的方法。

這兩件事應該不復雜,***件事是拼接代理類名,然后反射生成對象,第二件事強轉調(diào)用。

 

  1. public class Ioc{ 
  2.     public static void inject(Activity activity){ 
  3.         inject(activity , activity); 
  4.     } 
  5.     public static void inject(Object host , Object root){ 
  6.         Class<?> clazz = host.getClass(); 
  7.         String proxyClassFullName = clazz.getName()+"$$ViewInjector"
  8.        //省略try,catch相關代碼  
  9.         Class<?> proxyClazz = Class.forName(proxyClassFullName); 
  10.         ViewInjector viewInjector = (com.zhy.ioc.ViewInjector) proxyClazz.newInstance(); 
  11.         viewInjector.inject(host,root); 
  12.     } 
  13. public interface ViewInjector<T>{ 
  14.     void inject(T t , Object object); 

代碼很簡單,拼接代理類的全路徑,然后通過newInstance生成實例,然后強轉,調(diào)用代理類的inject方法。

這里一般情況會對生成的代理類做一下緩存處理,比如使用Map存儲下,沒有再生成,這里我們就不去做了。

這樣我們就完成了一個編譯時注解框架的編寫。

六、總結

本文通過具體的實例來描述了如何編寫一個基于編譯時注解的項目,主要步驟為:項目結構的劃分、注解模塊的實現(xiàn)、注解處理器的編寫以及對外公布的API模塊的編寫。通過文本的學習應該能夠了解基于編譯時注解這類框架運行的原理,以及自己如何去編寫這樣一類框架。

責任編輯:未麗燕 來源: 碼農(nóng)網(wǎng)
相關推薦

2022-06-20 16:18:25

MySQL安全免密碼輸入

2010-01-13 13:13:26

C++項目

2015-01-28 14:30:31

android代碼

2010-02-05 16:49:05

編寫Android 代

2020-03-30 17:43:13

開源開源項目編寫文檔

2010-02-03 17:29:06

Python編譯

2021-08-16 07:11:56

Go語言進程

2012-02-28 13:52:45

Adobe AIRAndroidFlash

2011-09-13 13:36:17

PhoneGap

2017-07-06 15:02:53

OpenGL ES架構GPU

2015-12-09 11:38:04

UprootIDS入侵檢測系統(tǒng)

2022-05-30 11:17:44

Spring容器配置

2022-06-09 07:27:14

JavaSpring容器

2012-07-11 10:51:37

編程

2015-10-12 16:37:39

前端編碼雙向編譯

2023-01-09 15:16:17

2009-12-28 16:03:42

編寫ADO.NET

2010-01-15 10:16:50

CentOS rpm安

2013-12-10 10:53:47

shellcode

2011-08-29 16:31:30

UbuntuAndroid
點贊
收藏

51CTO技術棧公眾號

亚欧日韩另类中文欧美| 久久大胆人体| 久久精品国产999大香线蕉| 久久久精品一区二区| 国产伦精品一区二区三区88av| 国产免费拔擦拔擦8x高清在线人 | 最近中文字幕免费mv2018在线| 国产麻豆成人精品| 欧美亚洲国产成人精品| 91大神福利视频| 国产伦乱精品| www国产成人免费观看视频 深夜成人网| 国产精品美女久久| 久久久综合久久| 成人影视亚洲图片在线| 精品国产一区久久| 亚洲va综合va国产va中文| caoporn视频在线观看| 国产精品美女视频| 九色91视频| 国产成人精品av在线观| 午夜偷拍福利视频| www.九色在线| 亚洲人成影院在线观看| 欧美一区激情视频在线观看| www.xxxx国产| 精品一区二区三区免费播放| 清纯唯美日韩制服另类| 久久激情免费视频| 国产精品成人a在线观看| 精品偷拍各种wc美女嘘嘘| 岛国av免费在线| 成年美女黄网站色大片不卡| 一区二区三区中文字幕| 在线成人性视频| 国产有码在线| 久久久久久久综合日本| 国产女主播一区二区| 国产人妻精品一区二区三区| 日韩黄色免费电影| 91精品国产99| 久草国产在线观看| 婷婷亚洲图片| 久久精品视频在线| 亚洲色图日韩精品| 国产欧美日韩精品高清二区综合区| 亚洲精品国偷自产在线99热| 亚洲视频在线不卡| 国产精品亚洲欧美一级在线 | 国产第一页视频| 狠狠操一区二区三区| 亚洲高清不卡在线观看| 日韩国产成人无码av毛片| 色噜噜狠狠狠综合欧洲色8| 亚洲人成影院在线观看| 强开小嫩苞一区二区三区网站| 3p在线观看| 国产精品青草综合久久久久99| 久久亚洲一区二区| 毛片免费在线播放| 黄色动漫在线观看| 99久久99久久综合| 精品国产一区二区三区四区精华| 欧美在线精品一区二区三区| 不卡视频免费播放| 久久亚洲免费| 最新电影电视剧在线观看免费观看| 国产午夜精品久久久久久久 | 秋霞午夜理伦电影在线观看| 国产精品不卡视频| 国产免费色视频| av免费网站在线| 亚洲小说欧美激情另类| 国产一区二区视频播放| 亚洲最大成人| 欧美三级乱人伦电影| 涩涩网站在线看| 北条麻妃一区二区三区在线| 日韩精品视频在线免费观看| 亚洲精品国产一区黑色丝袜| 日韩免费高清| 欧美极品少妇xxxxx| 国产午夜精品久久久久| 男男视频亚洲欧美| 91久久国产综合久久蜜月精品| 丰满人妻一区二区三区免费视频| 久久综合九色综合97婷婷| 欧美福利精品| 99视频免费在线观看| 欧美日韩美女在线| www.com久久久| 噜噜噜天天躁狠狠躁夜夜精品| 一区二区三区视频免费在线观看| 国产精品久久久免费看| 在线成人亚洲| 国产原创欧美精品| 深爱激情五月婷婷| 国产精品久久久久天堂| 免费在线观看视频a| yy6080久久伦理一区二区| 日韩欧美精品在线视频| 欧美日韩高清丝袜| 亚洲精品久久一区二区三区777| sis001亚洲原创区| 欧美视频在线观看一区| 性活交片大全免费看| 日韩av密桃| 97在线看福利| av免费观看在线| 国产午夜一区二区三区| 亚洲色成人www永久在线观看| 日本精品裸体写真集在线观看| 日韩三级视频在线看| 久久精品—区二区三区舞蹈| 亚洲午夜精品久久久久久app| 国产精品羞羞答答| 日韩欧美在线番号| 亚洲综合精品自拍| 日韩av.com| 欧美美女一区| 国产999在线| 欧美一区二区在线观看视频| 亚洲欧美一区二区三区孕妇| 91欧美视频在线| 国产a久久精品一区二区三区| 欧美精品www| 国产理论片在线观看| 国产日产欧美一区二区三区 | 五月天免费网站| 嫩草成人www欧美| 精品国产一区二区三区免费| 香蕉久久aⅴ一区二区三区| 欧美三级蜜桃2在线观看| 37p粉嫩大胆色噜噜噜| 亚洲国产精品一区制服丝袜| 91视频99| 国产蜜臀在线| 欧美变态tickling挠脚心| 色老板免费视频| 激情偷乱视频一区二区三区| 一区二区三区四区欧美| 国产经典一区| 中文字幕欧美日韩在线| 丰满人妻老熟妇伦人精品| 91在线观看下载| 凹凸国产熟女精品视频| 国产精品无码一区二区三区| 波多野结衣欧美| 欧美精品18videos性欧美| 亚洲精品久久久久久久久久久久久久| 亚洲免费观看高清完整| 最好看的中文字幕| 国产精品久久| 国产精品一区二区在线观看| 丁香花高清在线观看完整版| 欧美精品一区二区三区四区| 国产精品 欧美 日韩| av在线播放一区二区三区| 久久黄色片视频| 日韩av网站在线免费观看| 欧美在线视频免费观看| 国产理论电影在线观看| 欧美视频一二三区| 精品无码一区二区三区蜜臀| 国产精品12区| av免费观看国产| 国产精品一区2区3区| 国产精品福利在线观看| 国产精品久久麻豆| 欧美精品一区二区三区在线播放 | 欧美日韩1区2区| 亚洲区一区二区三| 国产91精品一区二区麻豆网站| 美脚丝袜脚交一区二区| 伊人成综合网yiren22| 国产精品久久久久91| 国产在线高清视频| 亚洲国产精品中文| 亚洲欧美日韩一区二区三区四区| 国产精品美日韩| 无码人妻精品一区二区三| 国产日韩专区| 宅男在线精品国产免费观看| 国产精品香蕉| 国产精品情侣自拍| 国产盗摄精品一区二区酒店| 亚洲丝袜av一区| 99在线精品视频免费观看软件| 精品成人国产在线观看男人呻吟| 青青草华人在线视频| 波多野结衣一区二区三区| 精品久久久久久中文字幕2017| 欧美高清不卡| 欧美一区二区三区在线观看视频| 老司机激情视频| 国内精品伊人久久久| 91免费看网站| 成人午夜sm精品久久久久久久| 欧美日韩999| av在线三区| 亚洲激情成人网| 国产情侣在线播放| 色呦呦国产精品| 一区视频免费观看| 国产日韩欧美麻豆| 亚洲观看黄色网| 国产一区不卡精品| 中文久久久久久| 亚洲狠狠婷婷| www.18av.com| 欧美激情另类| 日本一区免费在线观看| 久久久久久毛片免费看| 亚洲在线观看视频| 精品久久99| 668精品在线视频| 日韩123区| 尤物九九久久国产精品的特点 | 日韩中文字幕在线播放| 亚洲av激情无码专区在线播放| 91精品国产乱| 国产精品久久久午夜夜伦鲁鲁| 一本久久精品一区二区| 国产成人无码精品久在线观看| 亚洲精品中文在线观看| 肉色超薄丝袜脚交69xx图片| 国产调教视频一区| 国内精品久久99人妻无码| av高清久久久| 91精品啪在线观看国产| 国产成人av资源| 国产在线a视频| 国产很黄免费观看久久| 中文字幕第三区| 国产一区二区三区四区在线观看| 岛国毛片在线播放| 日本欧美在线看| 一级黄色香蕉视频| 丝瓜av网站精品一区二区| 一本久道综合色婷婷五月| 裸体素人女欧美日韩| 俄罗斯av网站| 久久福利影视| 欧美日韩在线成人| 天堂在线一区二区| 日韩欧美国产免费播放| 天天干天天曰天天操| 韩国一区二区视频| 三级黄色片免费观看| 国产精品资源网| 日批视频免费看| 大尺度一区二区| 最近中文字幕无免费| 99久久精品免费| 波多野吉衣中文字幕| 久久久久久久网| 国产一级久久久久毛片精品| 欧美激情一区二区三区蜜桃视频| 国产又黄又粗又猛又爽的| 日韩一区日韩二区| 久久久久香蕉视频| 亚洲超碰精品一区二区| 综合激情网五月| 欧美在线观看视频一区二区| 亚洲一卡二卡在线观看| 91精品婷婷国产综合久久性色| 精品人妻一区二区三区日产乱码 | 欧美午夜女人视频在线| 800av免费在线观看| 91福利视频久久久久| 国产又粗又猛又爽又黄视频| 精品人在线二区三区| 日韩三级电影网| 精品国产拍在线观看| 欧美人与动牲性行为| 69影院欧美专区视频| 日韩制服一区| 不卡视频一区二区三区| 台湾佬综合网| 午夜啪啪免费视频| 夜久久久久久| 一本一道久久a久久综合蜜桃| 国产a精品视频| 五月天综合视频| 一级日本不卡的影视| 一级黄色av片| 日韩一区二区麻豆国产| 香蕉视频网站在线| 这里只有视频精品| 成人高潮aa毛片免费| 国产成人精品免高潮在线观看 | 喷水一区二区三区| 亚洲av无一区二区三区久久| 久久久精品国产免费观看同学| 老湿机69福利| 在线观看国产日韩| 成人av无码一区二区三区| 亚洲视频在线观看视频| 91在线中字| 国产精品美乳在线观看| 超碰成人在线播放| 麻豆高清免费国产一区| 少妇精品一区二区| 亚洲精品中文在线| 在线免费观看日韩视频| 日韩精品在线私人| 91一区二区三区在线| 国产精品视频免费在线观看| 亚洲三级网页| 久久这里只有精品8| 久久国产日韩欧美精品| 丰满少妇一区二区| 亚洲国产人成综合网站| 国产喷水吹潮视频www| 国产一区二区激情| 欧美sm一区| 国产综合av一区二区三区| 亚洲激情五月| 日本中文字幕影院| 欧美激情在线看| 黄色在线视频网址| 亚洲第一福利在线观看| 性欧美高清come| 成人激情视频小说免费下载| 国产欧美日韩影院| 欧美 日韩 国产一区| caoporm超碰国产精品| 久视频在线观看| 国产精品女同一区二区三区| 日韩黄色在线播放| 日韩av网站在线| 欧美办公室脚交xxxx| 国产亚洲情侣一区二区无| 狠狠噜噜久久| 欧美图片自拍偷拍| 亚洲影院久久精品| 亚洲不卡免费视频| 欧美大胆在线视频| 成人影院网站ww555久久精品| 亚洲一区二区在线免费观看| 久久精品国产一区二区三| 五月天婷婷丁香网| 欧美视频一区二区三区在线观看| 在线视频三区| 国产欧美日韩91| 一区二区蜜桃| 国产资源中文字幕| 亚洲宅男天堂在线观看无病毒| 丁香花免费高清完整在线播放| 欧美激情成人在线视频| 国产精品流白浆在线观看| 无码中文字幕色专区| 久久免费的精品国产v∧| 国产一卡二卡三卡| 搡老女人一区二区三区视频tv| 在线成人免费| 丁香六月激情婷婷| 久久综合色一综合色88| 999视频在线| 日韩最新在线视频| 视频亚洲一区二区| 亚洲国产精品无码观看久久| 91啪九色porn原创视频在线观看| 午夜婷婷在线观看| 色一情一乱一区二区| 免费国产在线观看| 国产精品视频一二三区| 97超碰人人干| 一区二区三区回区在观看免费视频| 四虎精品永久免费| www.激情网| 久久久久久久国产精品影院| 艳妇乳肉豪妇荡乳av| 色综合天天综合网国产成人网| 视频福利一区| 欧美美女一级片| 亚洲大片一区二区三区| 撸视在线观看免费视频| 成人做爰www免费看视频网站| 亚洲人成久久| 最新中文字幕av| 欧美一区二区三区啪啪| 午夜影院在线播放| 一区二区国产日产| 99re热视频这里只精品| 中文字幕欧美色图| 久久久爽爽爽美女图片| 欧美三级三级| 欧美xxxxx少妇| 欧美三级视频在线播放| 91av久久| www亚洲国产| 久久噜噜亚洲综合| 午夜精品久久久久久久第一页按摩 | 免费看一级大片| 亚洲欧美三级伦理| 欧美视频三区| 五月婷婷激情久久| 午夜影视日本亚洲欧洲精品| 日本天堂在线观看|