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

用Kotlin開發(fā)Android項(xiàng)目是一種什么樣的感受?

移動(dòng)開發(fā)
從初學(xué) Kotlin,到嘗試性的寫一點(diǎn)體驗(yàn)代碼,再到實(shí)驗(yàn)性的做一些封裝工作,到最后摸爬滾打著寫了一個(gè)項(xiàng)目。不得不說過程中還是遇上了不少的問題,盡管有不少坑是源于我自己的選擇,比如使用了 anko 布局放棄了 xml,但是總體來說,這門語言帶給我的驚喜是完全足以讓我忽略路上的坎坷。

前言

從初學(xué) Kotlin,到嘗試性的寫一點(diǎn)體驗(yàn)代碼,再到實(shí)驗(yàn)性的做一些封裝工作,到***摸爬滾打著寫了一個(gè)項(xiàng)目。不得不說過程中還是遇上了不少的問題,盡管有不少坑是源于我自己的選擇,比如使用了 anko 布局放棄了 xml,但是總體來說,這門語言帶給我的驚喜是完全足以讓我忽略路上的坎坷。

這篇文章僅僅是想整理一下這一路走過來的一些感想和驚喜,隨著我對(duì) Kotlin 的學(xué)習(xí)和使用,會(huì)長期修改。

用Kotlin開發(fā)Android項(xiàng)目是一種什么樣的感受?

正文

1.有了空安全,再也不怕服務(wù)端返回空對(duì)象了

簡單一點(diǎn)的例子,那就是 String 和 String?是兩種不同的類型。String 已經(jīng)確定是不會(huì)為空,一定有值;而 String?則是未知的,也許有值,也許是空。在使用對(duì)象的屬性和方法的時(shí)候,String 類型的對(duì)象可以毫無顧忌的直接使用,而 String?類型需要你先做非空判斷。

 

  1. fun demo() { 
  2.     val string1: String = "string1" 
  3.     val string2: String? = null 
  4.     val string3: String? = "string3" 
  5.      
  6.     println(string1.length) 
  7.     println(string2?.length) 
  8.     println(string3?.length) 

輸出結(jié)果為:

 

  1. null 

盡管 string2 是一個(gè)空對(duì)象,也并沒有因?yàn)槲艺{(diào)用了它的屬性/方法就報(bào)空指針。而你所需要做的,僅僅是加一個(gè)"?"。

如果說這樣還體現(xiàn)不出空安全的好處,那么看下面的例子:

 

  1. val a: A? = A() 
  2. println(a?.b?.c) 

試想一下當(dāng)每一級(jí)的屬性皆有可能為空的時(shí)候,JAVA 中我們需要怎么處理?

2.轉(zhuǎn)型與智能轉(zhuǎn)換,省力又省心

我寫過這樣子的 JAVA 代碼

 

  1. if(view instanceof TextView) { 
  2.     TextView textView = (TextView) view
  3.     textView.setText("text"); 

而在 Kotlin 中的寫法則有所不同

 

  1. if(view is TextView) { 
  2.     TextView textView = view as TextView 
  3.     textView.setText("text"

縮減代碼之后對(duì)比更加明顯

 

  1. JAVA 
  2.  
  3. if(view instanceof TextView) { 
  4.     ((TextView) view).setText("text"); 
  5.  
  6. Kotlin 
  7.  
  8. if(view is TextView) { 
  9.     (view as TextView).setText("text"

相比于 JAVA 在對(duì)象前加 (Class) 這樣子的寫法,Kotlin 是在對(duì)象之后添加 as Class 來實(shí)現(xiàn)轉(zhuǎn)型。至少我個(gè)人而言,在習(xí)慣了 as Class 順暢的寫法之后,是再難以忍受 JAVA 中前置的寫法,哪怕有 cast 快捷鍵的存在,仍然很容易打斷我寫代碼的順序和思路

事實(shí)上,Kotlin 此處可以更簡單:

 

  1. if(view is TextView) { 
  2.     view.setText("text"

因?yàn)楫?dāng)前上下文已經(jīng)判明 view 就是 TextView,所以在當(dāng)前代碼塊中 view 不再是 View 類,而是 TextView 類。這就是 Kotlin 的智能轉(zhuǎn)換。

接著上面的空安全來舉個(gè)例子,常規(guī)思路下,既然 String 和 String? 是不同的類型,是不是我有可能會(huì)寫出這樣的代碼?

 

  1. val a: A? = A() 
  2. if (a != null) { 
  3.     println(a?.b) 

這樣子寫,Kotlin 反而會(huì)給你顯示一個(gè)高亮的警告,說這是一個(gè)不必要的 safe call。至于為什么,因?yàn)槟闱懊嬉呀?jīng)寫了 a != null 了啊,于是 a 在這個(gè)代碼塊里不再是 A? 類型, 而是 A 類型。

 

  1. val a: A? = A() 
  2. if (a != null) { 
  3.     println(a.b) 

智能轉(zhuǎn)換還有一個(gè)經(jīng)常出現(xiàn)的場(chǎng)景,那就是 switch case 語句中。在 Kotlin 中,則是 when 語法。

 

  1. fun testWhen(obj: Any) { 
  2.     when(obj) { 
  3.         is Int -> { 
  4.             println("obj is a int"
  5.             println(obj + 1) 
  6.         } 
  7.  
  8.         is String -> { 
  9.             println("obj is a string"
  10.             println(obj.length) 
  11.         } 
  12.  
  13.         else -> { 
  14.             println("obj is something i don't care"
  15.         } 
  16.     } 
  17.  
  18. fun main(args: Array<String>) { 
  19.     testWhen(98) 
  20.     testWhen("98"

輸出如下:

 

  1. obj is a int 
  2. 99 
  3. obj is a string 

可以看出在已經(jīng)判斷出是 String 的條件下,原本是一個(gè) Any 類的 obj 對(duì)象,我可以直接使用屬于 String 類的 .length 屬性。而在 JAVA 中,我們需要這樣做:

 

  1. System.out.println("obj is a string"
  2. String string = (String) obj; 
  3. System.out.println(string.length) 

或者

 

  1. System.out.println("obj is a string"
  2. System.out.println(((String) obj).length) 

前者打斷了編寫和閱讀的連貫性,后者嘛。。

Kotlin 的智能程度遠(yuǎn)不止如此,即便是現(xiàn)在,在編寫代碼的時(shí)候還會(huì)偶爾蹦一個(gè)高亮警告出來,這時(shí)候我才知道原來我的寫法是多余的,Kotlin 已經(jīng)幫我處理了好了。此處不再一一贅述。

3.比 switch 更強(qiáng)大的 when

通過上面智能轉(zhuǎn)化的例子,已經(jīng)展示了一部分 when 的功能。但相對(duì)于 JAVA 的 switch,Kotlin 的 when 帶給我的驚喜遠(yuǎn)遠(yuǎn)不止這么一點(diǎn)。

例如:

 

  1. fun testWhen(intInt) { 
  2.     when(int) { 
  3.         in 10 .. Int.MAX_VALUE -> println("${int} 太大了我懶得算"
  4.         2, 3, 5, 7 -> println("${int} 是質(zhì)數(shù)"
  5.         else -> println("${int} 不是質(zhì)數(shù)"
  6.     } 
  7.  
  8. fun main(args: Array<String>) { 
  9.     (0..10).forEach { testWhen(it) } 

輸出如下:

  1. 不是質(zhì)數(shù)
  2. 不是質(zhì)數(shù)
  3. 是質(zhì)數(shù)
  4. 是質(zhì)數(shù)
  5. 不是質(zhì)數(shù)
  6. 是質(zhì)數(shù)
  7. 不是質(zhì)數(shù)
  8. 是質(zhì)數(shù)
  9. 不是質(zhì)數(shù)
  10. 不是質(zhì)數(shù)
  11. 太大了我懶得算

和 JAVA 中死板的 switch-case 語句不同,在 when 中,我既可以用參數(shù)去匹配 10 到 Int.MAX_VALUE 的區(qū)間,也可以去匹配 2, 3, 5, 7 這一組值,當(dāng)然我這里沒有列舉所有特性。when 的靈活、簡潔,使得我在使用它的時(shí)候變得相當(dāng)開心(和 JAVA 的 switch 對(duì)比的話)

4.容器的操作符

自從迷上 RxJava 之后,我實(shí)在很難再回到從前,這其中就有 RxJava 中許多方便的操作符。而 Kotlin 中,容器自身帶有一系列的操作符,可以非常簡潔的去實(shí)現(xiàn)一些邏輯。

例如:

 

  1. (0 until container.childCount) 
  2.         .map { container.getChildAt(it) } 
  3.         .filter { it.visibility == View.GONE } 
  4.         .forEach { it.visibility = View.VISIBLE } 

上述代碼首先創(chuàng)建了一個(gè) 0 到 container.childCount - 1 的區(qū)間;再用 map 操作符配合取出 child 的代碼將這個(gè) Int 的集合轉(zhuǎn)化為了 childView 的集合;然后在用 filter 操作符對(duì)集合做篩選,選出 childView 中所有可見性為 GONE 的作為一個(gè)新的集合;最終 forEach 遍歷把所有的 childView 都設(shè)置為 VISIBLE。

這里再貼上 JAVA 的代碼作為對(duì)比。

 

  1. for(int i = 0; i < container.childCount - 1;  i++) { 
  2.     View childView = container.getChildAt(i); 
  3.     if(childView.getVisibility() == View.GONE) { 
  4.         childView.setVisibility(View.VISIBLE); 
  5.     } 

這里就不詳細(xì)的去描述這種鏈?zhǔn)降膶懛ㄓ惺裁磧?yōu)點(diǎn)了。

5.線程切換,so easy

既然上面提到了 RxJava,不得不想起 RxJava 的另一個(gè)優(yōu)點(diǎn)——線程調(diào)度。Kotlin 中有一個(gè)專為 Android 開發(fā)量身打造的庫,名為 anko,其中包含了許多可以簡化開發(fā)的代碼,其中就對(duì)線程進(jìn)行了簡化。

 

  1. async { 
  2.     val response = URL("https://www.baidu.com").readText() 
  3.     uiThread { 
  4.         textView.text = response 
  5.     } 

上面的代碼很簡單,通過 async 方法將代碼實(shí)現(xiàn)在一個(gè)異步的線程中,在讀取到 http 請(qǐng)求的響應(yīng)了之后,再通過 uiThread 方法切換回 ui 線程將 response 顯示在 textView 上。

拋開內(nèi)部的實(shí)現(xiàn),你再也不需要為了一個(gè)簡簡單單的異步任務(wù)去寫一大堆的無效代碼。按照慣例,這里似乎應(yīng)該貼上 JAVA 的代碼做對(duì)比,但請(qǐng)?jiān)徫也幌胨⑵?啊哈哈)

6.一個(gè)關(guān)鍵字實(shí)現(xiàn)單例

沒錯(cuò),就是一個(gè)關(guān)鍵字就可以實(shí)現(xiàn)單例:

 

  1. object Log { 
  2.     fun i(string: String) { 
  3.         println(string) 
  4.     } 
  5.  
  6. fun main(args: Array<String>) { 
  7.     Log.i("test"

再見,單例模式

7.自動(dòng) getter、setter 及 class 簡潔聲明

JAVA 中有如下類

 

  1. class Person { 
  2.     private String name
  3.  
  4.     public Person(String name) { 
  5.         this.name = name
  6.     } 
  7.  
  8.     public void setName(String name) { 
  9.         this.name = name
  10.     } 
  11.  
  12.     public void getName() { 
  13.         return name
  14.     } 
  15.  
  16. Person person = new Person("張三"); 

Person person = new Person("張三");

可以看出,標(biāo)準(zhǔn)寫法下,一個(gè)屬性對(duì)應(yīng)了 get 和 set 兩個(gè)方法,需要手動(dòng)寫的代碼量相當(dāng)大。當(dāng)然有快捷鍵幫助我們生成這些代碼,但是考慮到各種復(fù)雜情形總歸不***。

而 Kotlin 中是這樣的:

 

  1. class Person(var name: String) 
  2. val person = Person("張三"); 

還可以添加默認(rèn)值:

 

  1. class Person(var name: String = "張三"
  2. val person = Person() 

再附上我項(xiàng)目中一個(gè)比較復(fù)雜的數(shù)據(jù)類:

 

  1. data class Column
  2.         var subId: String?, 
  3.         var subTitle: String?, 
  4.         var subImg: String?, 
  5.         var subCreatetime: String?, 
  6.         var subUpdatetime: String?, 
  7.         var subFocusnum: Int?, 
  8.         var lastId: String?, 
  9.         var lastMsg: String?, 
  10.         var lastType: String?, 
  11.         var lastMember: String?, 
  12.         var lastTIme: String?, 
  13.         var focus: String?, 
  14.         var subDesc: String?, 
  15.         var subLikenum: Int?, 
  16.         var subContentnum: Int?, 
  17.         var pushSet: String? 

一眼望去,沒有多余代碼。這是為什么我認(rèn)為 Kotlin 代碼比 JAVA 代碼要更容易寫得干凈的原因之一。

8. DSL 式編程

說起 dsl ,Android 開發(fā)者接觸的最多的或許就是 gradle 了

例如:

 

  1. android { 
  2.     compileSdkVersion 23 
  3.     buildToolsVersion "23.0.2" 
  4.  
  5.     defaultConfig { 
  6.         applicationId "com.zll.demo" 
  7.         minSdkVersion 15 
  8.         targetSdkVersion 23 
  9.         versionCode 1 
  10.         versionName "1.0" 
  11.     } 
  12.     buildTypes { 
  13.         release { 
  14.             minifyEnabled false 
  15.             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
  16.         } 
  17.     } 

這就是一段 Groovy 的 DSL,用來聲明編譯配置

那么在 Android 項(xiàng)目的代碼中使用 DSL 是一種什么樣的感覺呢?

 

  1. override fun onCreate(savedInstanceState: Bundle?) { 
  2.     super.onCreate(savedInstanceState) 
  3.  
  4.     val homeFragment = HomeFragment() 
  5.     val columnFragment = ColumnFragment() 
  6.     val mineFragment = MineFragment() 
  7.  
  8.     setContentView( 
  9.             tabPages { 
  10.                 backgroundColor = R.color.white 
  11.                 dividerColor = R.color.colorPrimary 
  12.                 behavior = ByeBurgerBottomBehavior(context, null
  13.  
  14.                 tabFragment { 
  15.                     icon = R.drawable.selector_tab_home 
  16.                     body = homeFragment 
  17.                     onSelect { toast("home selected") } 
  18.                 } 
  19.  
  20.                 tabFragment { 
  21.                     icon = R.drawable.selector_tab_search 
  22.                     body = columnFragment 
  23.                 } 
  24.  
  25.                 tabImage { 
  26.                     imageResource = R.drawable.selector_tab_photo 
  27.                     onClick { showSheet() } 
  28.                 } 
  29.  
  30.                 tabFragment { 
  31.                     icon = R.drawable.selector_tab_mine 
  32.                     body = mineFragment 
  33.                 } 
  34.             } 
  35.     ) 

 

[[231055]]

沒錯(cuò),上面的代碼就是用來構(gòu)建這個(gè)主界面的 viewPager + fragments + tabBar 的。以 tabPages 作為開始,設(shè)置背景色,分割線等屬性;再用 tabFrament 添加 fragment + tabButton,tabImage 方法則只添加 tabButton。所見的代碼都是在做配置,而具體的實(shí)現(xiàn)則被封裝了起來。

前面提到過 anko 這個(gè)庫,其實(shí)也可以用來替代 xml 做布局用:

 

  1. override fun onCreate(savedInstanceState: Bundle?) { 
  2.     super.onCreate(savedInstanceState) 
  3.  
  4.     verticalLayout { 
  5.         textView { 
  6.             text = "這是標(biāo)題" 
  7.         }.lparams { 
  8.             width = matchParent 
  9.             height = dip(44) 
  10.         } 
  11.  
  12.         textView { 
  13.             text = "這是內(nèi)容" 
  14.             gravity = Gravity.CENTER 
  15.         }.lparams { 
  16.             width = matchParent 
  17.             height = matchParent 
  18.         } 
  19.     } 

相比于用 JAVA 代碼做布局,這種 DSL 的方式也是在做配置,把布局的實(shí)現(xiàn)代碼封裝在了背后,和 xml 布局很接近。

關(guān)于 DSL 和 anko 布局,以后會(huì)有專門的文章做介紹,這里就此打住。

9.委托/代理,SharedPreference 不再麻煩

通過 Kotlin 中的委托功能,我們能輕易的寫出一個(gè) SharedPreference 的代理類

 

  1. class Preference<T>(val context: Context, val name: String?, val default: T) : ReadWriteProperty<Any?, T> { 
  2.     val prefs by lazy { 
  3.         context.getSharedPreferences("xxxx", Context.MODE_PRIVATE) 
  4.     } 
  5.  
  6.     override fun getValue(thisRef: Any?, property: KProperty<*>): T = with(prefs) { 
  7.         val res: Any = when (default) { 
  8.             is Long -> { 
  9.                 getLong(name, 0) 
  10.             } 
  11.             is String -> { 
  12.                 getString(namedefault
  13.             } 
  14.             is Float -> { 
  15.                 getFloat(namedefault
  16.             } 
  17.             is Int -> { 
  18.                 getInt(namedefault
  19.             } 
  20.             is Boolean -> { 
  21.                 getBoolean(namedefault
  22.             } 
  23.             else -> { 
  24.                 throw IllegalArgumentException("This type can't be saved into Preferences"
  25.             } 
  26.         } 
  27.         res as T 
  28.     } 
  29.  
  30.     override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) = with(prefs.edit()) { 
  31.         when (value) { 
  32.             is Long -> putLong(name, value) 
  33.             is String -> putString(name, value) 
  34.             is Float -> putFloat(name, value) 
  35.             is Int -> putInt(name, value) 
  36.             is Boolean -> putBoolean(name, value) 
  37.             else -> { 
  38.                 throw IllegalArgumentException("This type can't be saved into Preferences"
  39.             } 
  40.         }.apply() 
  41.     } 

暫且跳過原理,我們?nèi)タ丛趺词褂?/p>

 

  1. class EntranceActivity : BaseActivity() { 
  2.      
  3.     private var userId: String by Preference(this, "userId"""
  4.  
  5.     override fun onCreate(savedInstanceState: Bundle?) { 
  6.         testUserId() 
  7.     } 
  8.      
  9.     fun testUserId() { 
  10.         if (userId.isEmpty()) { 
  11.             println("userId is empty"
  12.             userId = "default userId" 
  13.         } else { 
  14.             println("userId is $userId"
  15.         } 
  16.     } 

重復(fù)啟動(dòng) app 輸出結(jié)果:

 

  1. userId is empty 
  2. userId is default userId 
  3. userId is default userId 
  4. ... 

***次啟動(dòng) app 的時(shí)候從 SharedPreference 中取出來的 userId 是空的,可是后面卻不為空。由此可見,userId = "default userId" 這句代碼成功的將 SharedPreference 中的值修改成功了。

也就是說,在這個(gè) Preference 代理的幫助下,SharedPreference 存取操作變得和普通的對(duì)象調(diào)用、賦值一樣的簡單。

10.擴(kuò)展,和工具類說拜拜

很久很久以前,有人和我說過,工具類本身就是一種違反面向?qū)ο笏枷氲臇|西。可是當(dāng)時(shí)我就想了,你不讓我用工具類,那有些代碼我該怎么寫呢?直到我知道了擴(kuò)展這個(gè)概念,我才豁然開朗。

 

  1. fun ImageView.displayUrl(url: String?) { 
  2.     if (url == null || url.isEmpty() || url == "url") { 
  3.         imageResource = R.mipmap.ic_launcher 
  4.     } else { 
  5.         Glide.with(context) 
  6.                 .load(ColumnServer.SERVER_URL + url) 
  7.                 .into(this) 
  8.     } 
  9. ... 
  10. val imageView = findViewById(R.id.avatarIv) as ImageView 
  11. imageView.displayUrl(url) 

上述代碼可理解為:

  1. 我給 ImageView 這個(gè)類擴(kuò)展了一個(gè)名為 displayUrl 的方法,這個(gè)方法接收一個(gè)名為 url 的 String?類對(duì)象。如不出意外,會(huì)通過 Glide 加載這個(gè) url 的圖片,顯示在當(dāng)前的 imageView 上;
  2. 我在另一個(gè)地方通過 findViewById 拿到了一個(gè) ImageView 類的實(shí)例,然后調(diào)用這個(gè) imageView 的displayUrl 方法,試圖加載我傳入的 url

通過擴(kuò)展來為 ImageView 添加方法,相比于通過繼承 ImageView 來寫一個(gè) CustomImageView,再添加方法而言,侵入性更低,不需要在代碼中全寫 CustomImageView,也不需要在 xml 布局中將包名寫死,造成移植的麻煩。

這事用工具類當(dāng)然也可以做,比如做成 ImageUtil.displayUrl(imageView, url),但是工具類閱讀起來并沒有擴(kuò)展出來的方法讀起來更自然更流暢。

擴(kuò)展是 Kotlin 相比于 JAVA 的一大殺器

責(zé)任編輯:未麗燕 來源: 安卓巴士
相關(guān)推薦

2018-05-30 15:07:37

KotlinAndroid開發(fā)

2019-07-08 17:34:29

共享辦公ideaPod文印

2019-04-03 14:51:18

CPU性能工藝

2015-11-03 08:51:21

程序員怪物

2020-11-06 17:49:38

程序員技術(shù)開發(fā)

2015-09-09 09:41:28

十年代碼

2017-03-10 09:09:41

C語言體驗(yàn)

2015-12-03 09:23:25

程序員產(chǎn)品經(jīng)理

2015-04-08 10:40:09

2021-01-14 21:46:02

Vue.jsReact框架

2010-08-02 13:30:34

移動(dòng)開發(fā)移動(dòng)開發(fā)平臺(tái)

2017-04-06 15:00:38

編程語言

2020-04-07 08:05:51

程序員互聯(lián)網(wǎng)職業(yè)

2017-08-17 13:14:01

2019-01-11 10:39:24

軟件架構(gòu)虛擬空間機(jī)器人

2015-02-04 10:55:14

2025-01-06 08:00:54

2016-08-30 21:09:33

2014-02-25 09:55:07

敏捷開發(fā)

2015-08-31 09:27:21

語言界面UI
點(diǎn)贊
收藏

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

在线精品视频一区| 视频三区在线| 久久经典综合| 日韩有码视频在线| 国产又粗又猛大又黄又爽| 肉体视频在线| 久久夜色精品国产欧美乱极品| 日本韩国欧美精品大片卡二| 99精品中文字幕| 亚洲国产高清在线观看| 午夜不卡在线视频| 五码日韩精品一区二区三区视频| 国产精品无码久久av| 亚洲激情综合| 中文字幕成人精品久久不卡 | 在线观看免费视频你懂的| 不卡视频免费播放| 国产精品高清在线观看| 久久久精品视频在线| 国产成人三级| 欧美精品一区二区三区视频| 在线看免费毛片| 午夜影视一区二区三区| 亚洲欧洲综合另类在线| 欧美日韩亚洲一区二区三区在线观看| 国产精品久久久久毛片| 国产亚洲毛片在线| 欧美成人一区在线| 四虎成人免费影院| 麻豆一区二区| 日韩精品中文字幕在线一区| 天天爽夜夜爽一区二区三区| 欧美激情20| 亚洲永久免费av| 在线码字幕一区| 国产高清视频在线| 91蜜桃在线免费视频| 不卡一区二区三区视频| 亚洲一区二区影视| 日韩国产欧美在线播放| 91国产美女视频| 久操视频免费在线观看| 一区二区三区四区在线观看国产日韩| 亚洲视频国产视频| 自拍视频一区二区| 国产香蕉精品| 精品99久久久久久| 韩国三级在线看| 国产精品久久久久久久久久辛辛| 欧美日本免费一区二区三区| 日韩无套无码精品| 中老年在线免费视频| 亚洲国产欧美日韩另类综合 | 美女又爽又黄免费| 国产精品亚洲综合在线观看 | 亚洲少妇30p| 亚洲自拍偷拍二区| 91亚洲精选| 国产精品入口麻豆九色| 无码免费一区二区三区免费播放| 丁香婷婷在线观看| 中文字幕国产一区二区| 日本视频一区二区不卡| 成年在线电影| 中文无字幕一区二区三区| 亚洲 国产 日韩 综合一区| 国产高清在线| 最新不卡av在线| 大地资源网在线观看免费官网| 日本在线www| 亚洲人精品一区| 国产免费一区二区视频| 日本在线高清| 欧美亚洲精品一区| 福利视频999| 98视频精品全部国产| 亚洲第一男人天堂| 国产全是老熟女太爽了| 色小子综合网| 欧美激情高清视频| 亚洲 欧美 视频| 日韩电影在线免费观看| 成人春色激情网| 亚洲精品久久久狠狠狠爱| 成人一级片网址| 欧美日韩综合网| 日本韩国在线视频爽| 曰韩精品一区二区| 少妇高潮毛片色欲ava片| 美女18一级毛片一品久道久久综合| 色噜噜久久综合| www.亚洲自拍| 婷婷五月色综合香五月| 中文字幕日韩有码| 日韩欧美123区| 国产一区导航| 成人午夜激情免费视频| 手机看片1024日韩| 国产精品久久久久久亚洲伦| 日韩激情视频一区二区| 日韩成人av电影| 日韩一区二区精品在线观看| 国产传媒第一页| 亚洲a在线视频| 欧美一区二区色| 99久久久久成人国产免费| 99精品国产91久久久久久| 亚洲在线视频一区二区| 51漫画成人app入口| 欧美三级电影一区| 中出视频在线观看| **女人18毛片一区二区| 欧美最顶级丰满的aⅴ艳星| 国产偷拍一区二区| 国产日本亚洲高清| 免费看毛片的网址| 97精品资源在线观看| 亚洲美女福利视频网站| 欧美精品xxxxx| 蜜臀a∨国产成人精品| 国产一区不卡在线观看| 91在线视频免费看| 欧美日韩在线看| 午夜影院福利社| 国产韩日影视精品| 国产精品xxxxx| 少妇喷水在线观看| 亚洲欧美区自拍先锋| 久久九九国产视频| 窝窝社区一区二区| 国模叶桐国产精品一区| 午夜精品在线播放| 亚洲四区在线观看| 国产又粗又长又大的视频| 日本福利一区| 97视频网站入口| 亚洲精品福利网站| 亚洲免费观看高清完整版在线观看| 国产主播中文字幕| 久久综合欧美| 国产aⅴ夜夜欢一区二区三区| 殴美一级特黄aaaaaa| 亚洲精品乱码久久久久久| av免费一区二区| 人人狠狠综合久久亚洲婷| 国产成人精品久久亚洲高清不卡| 手机av免费在线观看| 亚洲福利国产精品| 欧美久久久久久久久久久| 午夜视频精品| 91久久伊人青青碰碰婷婷| 黄色网页在线免费看| 欧美日韩视频一区二区| 91麻豆制片厂| 男女性色大片免费观看一区二区 | 香蕉视频免费网站| 欧美淫片网站| 成人资源视频网站免费| 激情影院在线| 欧美一级黄色录像| 国产大学生自拍| 粉嫩av一区二区三区在线播放| 国产 国语对白 露脸| 18国产精品| 97视频在线看| 国产免费永久在线观看| 精品视频一区二区不卡| 一区二区三区在线播放视频| 国产一区在线观看麻豆| 69精品丰满人妻无码视频a片| 精品国产亚洲日本| 欧美激情综合亚洲一二区| 黑人操亚洲女人| 欧美性高潮在线| 日本成人免费视频| 国产综合久久久久影院| 精品一区二区三区无码视频| 欧美一区 二区| 国产精品9999| gogo在线观看| 亚洲国产精品yw在线观看| 久久久久久久久久久影院| 国产亚洲欧美日韩在线一区| 可以看污的网站| 精品99视频| 欧美精品免费观看二区| 高清欧美日韩| 久久久久久91| 番号在线播放| 亚洲成年人在线播放| 国产性生活视频| 亚洲精品成人在线| 三级黄色片网站| 精品亚洲免费视频| 日韩国产一级片| 日韩精品免费一区二区三区| 51午夜精品| 性欧美hd调教| 欧美国产欧美亚洲国产日韩mv天天看完整| 五月天婷婷激情网| 91.麻豆视频| 国产又黄又粗又爽| 亚洲精品日日夜夜| 99久久久无码国产精品衣服| 国产精品一区三区| 精品久久久久久久无码| 国产精品mm| 亚洲欧美国产不卡| 日韩伦理一区二区三区| 91麻豆国产精品| 国产精品扒开腿做爽爽爽视频软件| 久久久精品免费| 青青草手机在线| 日韩午夜精品视频| 中文字幕 欧美激情| 午夜成人免费视频| 欧美日韩在线视频免费| 中文在线资源观看网站视频免费不卡 | 国产精品99久久久久久久| 福利视频亚洲| 国产999精品| av在线理伦电影| 日韩一区二区欧美| 激情小说 在线视频| 日韩av综合网| 亚洲女人18毛片水真多| 正在播放亚洲一区| 国产女优在线播放| 日韩欧美在线视频免费观看| 国产午夜免费视频| 一区二区三区在线观看国产| 国产成人免费在线观看视频| 国产亚洲成年网址在线观看| 久久一区二区电影| jlzzjlzz亚洲日本少妇| 91精品国产高清91久久久久久 | 色婷婷综合久久久久中文一区二区| 激情五月婷婷在线| 亚洲欧美区自拍先锋| 黄色香蕉视频在线观看| 中文av一区二区| 欧洲性xxxx| 国产精品日产欧美久久久久| 亚洲最大成人综合网| 久久麻豆一区二区| 中文字幕丰满孑伦无码专区| 99久久国产免费看| xxxxxx黄色| 2022国产精品视频| 深爱五月激情网| 久久久久久久久久久久久久久99| 99re久久精品国产| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 久久国产生活片100| 男人的天堂日韩| 青青草成人在线观看| 国产成人黄色网址| 极品少妇一区二区| 先锋资源在线视频| 国产99久久久国产精品免费看| 精品人妻一区二区乱码| 粉嫩欧美一区二区三区高清影视 | 大奶在线精品| 精品国产乱码久久久久久蜜柚 | 欧美一级黄色录像片| 一区二区日韩欧美| 男女视频网站在线观看| 欧美一级一区| 日本人69视频| 国产成人啪免费观看软件| 色哟哟视频在线| 久久综合九色欧美综合狠狠| 亚洲av熟女国产一区二区性色| 国产精品高潮呻吟| 九九九久久久久| 黑人巨大精品欧美一区二区免费| 国产成人无码专区| 538在线一区二区精品国产| 亚洲第一天堂网| 亚洲欧美国产一本综合首页| 日本高清中文字幕在线| 欧美激情图片区| 欧美色网在线| 亚洲曰本av电影| 蜜桃国内精品久久久久软件9| 亚洲高清在线观看一区| 很黄很黄激情成人| 毛片一区二区三区四区| 精品系列免费在线观看| 2一3sex性hd| 国产精品久久一卡二卡| 成人免费看片98| 欧日韩精品视频| 国产999久久久| 亚洲男人天堂视频| 同心难改在线观看| 最近2019年手机中文字幕 | 国产精品zjzjzj在线观看| 欧美一区二区福利| 婷婷六月综合| 久久www视频| 日本怡春院一区二区| 一个人看的视频www| 成人av网址在线观看| 在线观看国产精品一区| 亚洲激情在线激情| 黄色av一区二区| 精品福利av导航| 伊人免费在线| 国产99久久久欧美黑人| 一区二区三区四区视频免费观看| 日韩一区二区电影在线观看| 午夜精品婷婷| 538在线视频观看| 不卡的av在线| www.av视频| 欧美视频精品在线观看| 日韩私人影院| 欧美久久精品一级黑人c片| 欧美大胆性生话| 国模精品娜娜一二三区| 久久久久久免费视频| 欧美女人性生活视频| 国产不卡视频在线观看| 成人无码av片在线观看| 精品免费在线视频| 99草在线视频| 最近中文字幕日韩精品| 成人免费网站视频| 国产精品免费一区二区三区在线观看| 99热在线成人| 欧美国产日韩在线播放| 成人aa视频在线观看| 青青草在线观看视频| 欧美日韩黄视频| 日韩性xxxx| 欧美激情亚洲国产| 清纯唯美激情亚洲| 欧美亚洲视频一区| 男人的j进女人的j一区| 精品无码一区二区三区| 日韩欧亚中文在线| 熟妇人妻系列aⅴ无码专区友真希 熟妇人妻av无码一区二区三区 | 国产成人手机在线| 欧美成人精品不卡视频在线观看| 四虎国产精品成人免费影视| 日韩欧美精品一区二区三区经典| 国产精品mv在线观看| 在线一区二区不卡| 国产精品美女一区二区三区 | 国产精品69av| 亚洲人亚洲人色久| 毛片av免费在线观看| 91美女在线观看| 久久久久久久伊人| 欧美精品一区二区三区高清aⅴ| 色图在线观看| 国产伦精品一区二区三区视频黑人| 欧美fxxxxxx另类| 国产乱国产乱老熟300部视频| 亚洲免费观看高清完整版在线观看熊 | 久久夜色精品国产噜噜av小说| 亚洲bbw性色大片| 日韩**一区毛片| 色哟哟精品观看| 91高清在线观看| 午夜小视频在线| 国产精品福利片| 偷窥自拍亚洲色图精选| 十八禁视频网站在线观看| 久久久久国产一区二区三区四区| 日本一区二区三区久久| 日韩在线一区二区三区免费视频| 精品视频一区二区三区| 日本老太婆做爰视频| 成人午夜碰碰视频| 国产免费a视频| 色视频www在线播放国产成人 | 国产精品久久久一区二区三区| 欧美成人久久| 国产艳俗歌舞表演hd| 色婷婷国产精品综合在线观看| 日韩精品毛片| 97视频资源在线观看| 亚洲黄色天堂| 国产精品综合激情| 91精品国产欧美一区二区| 极品在线视频| 色姑娘综合av| 国产乱码字幕精品高清av| 久久精品国产亚洲AV无码麻豆 | 欧美精品一二| 色黄视频免费看| 五月激情六月综合| 欧美天天影院| 国外成人在线视频网站| 久久99久久99| 91精品国产高潮对白| 亚洲韩国青草视频| 2020国产精品小视频|