成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

iOS混合應(yīng)用開發(fā)入門

移動開發(fā) iOS 移動應(yīng)用
這篇文章將會對混合應(yīng)用的主題進行更深入的探討。我們將會以講解混合應(yīng)用的構(gòu)成做為開始。然后,我們將會看下混合應(yīng)用能帶來的優(yōu)勢,并且也會提供更 多消極方面的細節(jié)。我們將會檢驗一些可以使混合應(yīng)用在感覺上更加像一個原生應(yīng)用的選項,然后給你提供一些用來優(yōu)化性能,外觀以及體驗的建議。

介紹

上周(譯者:原文成于2012.07.06),紐約時報透露說Facebook一直在致力于對其iOS應(yīng)用進行重大升級。這個事實本身沒有什么新聞價值。Facebook當然一直在致力于對其iOS應(yīng)用進行重大升級。但是,這次的升級相當有新聞價值。就如何構(gòu)建和維護越來越多的移動應(yīng)用套件而言,F(xiàn)acebook正在計劃一個意義重大的航線修正(譯者:技術(shù)轉(zhuǎn)型)。

到目前為止,F(xiàn)acebook公開的移動策略是為了避免「重復(fù)寫四次相同代碼」(之后會更多),而發(fā)布混合應(yīng)用 (hybrid apps)到各主流 平臺。理論上講,這個想法很完美:當你可以為相同的功能只維護一個代碼庫的時候,誰愿意為此維護多個呢?但是,實際的情況是,F(xiàn)acebook的應(yīng)用在任 何平臺上都沒有「原生」的感覺,同時也被嚴重的性能問題所折磨,并普遍的被其用戶所辱罵。

這篇文章將會對混合應(yīng)用的主題進行更深入的探討。我們將會以講解混合應(yīng)用的構(gòu)成做為開始。然后,我們將會看下混合應(yīng)用能帶來的優(yōu)勢,并且也會提供更 多消極方面的細節(jié)。我們將會檢驗一些可以使混合應(yīng)用在感覺上更加像一個原生應(yīng)用的選項,然后給你提供一些用來優(yōu)化性能,外觀以及體驗的建議。最后,我們會把注意力轉(zhuǎn)回到Facebook上,為了理解他們是如何成為今天這個樣子的,我們將會更細致的查看他們iOS應(yīng)用的歷史。

從個人的角度來說,我不會為iOS構(gòu)建一個混合應(yīng)用,除非我必須這么做不可。我不認為混合應(yīng)用在iOS上表現(xiàn)良好: 它們比較慢,也比較笨拙,并且從 來沒有原生應(yīng)用那樣的外觀和體驗。但是,在合適的場景下,它們所能提供的優(yōu)勢能抵掉它們的劣勢。為了學(xué)習(xí)關(guān)于混合應(yīng)用的所有內(nèi)容,什么是能做的,什么是不 能做的,并且它們是否滿足你的需求,請繼續(xù)往下讀。

什么是混合應(yīng)用?

通常來說,一個iPhone應(yīng)用是利用Cocoa Touch框架以純Objective C來構(gòu)建的。你可能會有一個UITabBarController,上面安放了一些視圖控制器(view controllers)。這些視圖控制器可能是UITableViewController的子類,或者也有可能是UIViewController, 其UI是使用XIB所定義或者在代碼中定義。有時候,一個視圖控制器上可能會安放一個UIWebView控件,用來在一個應(yīng)用的內(nèi)部展示web內(nèi)容或長文本內(nèi)容。

混合應(yīng)用用HTML,CSS和Javascript而不是Objective-C來實現(xiàn)部分或者所有的客戶端代碼。一個特定應(yīng)用的屏幕實際上可能包含一個UIWebView,用它來渲染服務(wù)端返回的標記語言(譯者:即HTML)并且 解釋服務(wù)端返回的代碼(譯者:JavaScript)而不是Objective C。

一些應(yīng)用,比如像Instapaper和Pocket,是高度依賴web視圖來實現(xiàn)其關(guān)鍵的應(yīng)用功能的。 Instapaper和Pocket對 web視圖的使用采取了一個務(wù)實的方案:兩個應(yīng)用的主函數(shù)都是展示重新格式化的web內(nèi)容,所以只用web視圖來展示HTML是有道理的。

就像在下面的類型列表中即將看到的那樣,F(xiàn)acebook盡可能的在它們的iOS應(yīng)用中使用HTML,其本質(zhì)上是把http://touch.facebook.com的一個版本填充進了一個Objective C的殼里邊。它們在一些限定的應(yīng)用特性中使用Objective C,比如登錄窗口和它們曾經(jīng)獨一無二的滑出菜單界面。

最后,還存在可以添加到iPhone主屏的移動站點。這些站點是100%用HTML構(gòu)建的,并且特定的運行在移動版Safari中。

應(yīng)用的類型應(yīng)用類型

類型

 

例子

 

完全原生

 

Path 2.0和其他完全利用Cocoa Touch框架用Objective C所實現(xiàn)的應(yīng)用。

 

一些web視圖

 

Instapaper和Pocket都是使用web視圖來實現(xiàn)關(guān)鍵的應(yīng)用功能,但是其他的功能是用Objective C來實現(xiàn)的。

 

最小化Objective C

 

比如Facebook。盡可能的使用HTML/JS/CSS來實現(xiàn)的應(yīng)用,并且只有很少的組件是原生的。

 

純HTML

 

就像它描述的那樣

 

混合應(yīng)用的優(yōu)勢

為什么你想要創(chuàng)建一個混合應(yīng)用?這兒有一些原因,比如產(chǎn)品開發(fā)和更新的速度,輕松的進行A/B測試,以及通過讓前端web開發(fā)人員加入到iOS開發(fā)中,可以增加可用的開發(fā)人員數(shù)量。

開發(fā)速度

盡管開發(fā)一個外觀完美,行為原生的移動web體驗是不太可能一夜完成 的,但是在較短的時間內(nèi)開發(fā)一個合宜的體驗相對來說是比較簡單的。開發(fā)一個得體的web體驗,并且把它加載到一個UIWebView中肯定比開發(fā)一個 JSON API,并用Objective C來寫一些前端代碼要容易。由于這個原因,一些開發(fā)者可能比較喜歡用HTML來交付那些用來檢驗想法的功能,然后接下來當功能的價值被證實了的時候再把功 能的代碼替換成原生代碼。

投入市場的時間是公司之間的關(guān)鍵區(qū)分點,發(fā)布日期延遲幾周或者甚至幾個月對于資源受限(limited runway)的創(chuàng)業(yè)公司來說這可能意味著生與死的區(qū)別。

發(fā)布更新的速度

通過HTML來提供產(chǎn)品功能的另一個優(yōu)勢是你可以在不向蘋果發(fā)起 應(yīng)用更新請求的情況下去更新你應(yīng)用的功能集合,并且不需要等待蘋果幾周的審批過程。 快速的進行改變,修復(fù)問題以及能擴展你應(yīng)用的功能,這可以為你提供一個用來超越對手的重要競爭優(yōu)勢,你的競爭對手由于每個小的改動都需要經(jīng)過蘋果的審批過 程,所以它們的靈活性就比較低。

早上想要的新功能,這天結(jié)束的時候就可以發(fā)布,并且晚上就可以觀測用戶的使用情況,以便第二天早上就可以對其進行優(yōu)化,調(diào)整或者刪除,這是對體驗進行打磨非常強大的方法,而體驗恰恰是你的應(yīng)用可以在市場上取得成功的必需條件。

A/B測試

與開發(fā)的速度和發(fā)布更新的速度都相關(guān)的是快速的對用戶進行A/B測試或者分組測試的 能力。比如,你可能想測試一下你應(yīng)用上的新feed功能,在其自身包含一個Like按鈕的情況下和只在feed內(nèi)容詳情頁面包含這個按鈕的情況,用戶使用 率是否有所提高。用HTML來實現(xiàn)feed功能,你可以很容易的對這個更改進行區(qū)分測試,為了從統(tǒng)計數(shù)據(jù)上來看這個重要的用戶行為是否發(fā)生,可以只在一組 用戶中展示這個按鈕。

在原生代碼中執(zhí)行A/B測試不是不可能的,但是準備測試用例會更加具有挑戰(zhàn)性,并且對比一個混合應(yīng)用來說,從測試用例中返回對應(yīng)的新數(shù)據(jù),這個過程將會顯著地耗費更多的時間。如果你對如何在Objective C中實現(xiàn)A/B測試好奇,Little Big Thinkers上有一篇好文章展示了它們?nèi)绾卧趇Phone上進行A/B測試(譯者:翻墻)。

App開發(fā)的民主方式

如果你曾經(jīng)嘗試過雇傭一個iOS開發(fā)者(或者如果你是一個 iOS承包商),你知道對靠譜iOS開發(fā)者的需求與可雇傭的人來說早就已經(jīng)是供不應(yīng)求。混 合應(yīng)用可以大大的增加你所需要的靠譜開發(fā)者數(shù)量,因為你可以讓你任何的前端開發(fā)人員轉(zhuǎn)做你iOS應(yīng)用中的功能開發(fā),假設(shè)他們已經(jīng)熟悉 Javascript,HTML,CSS和你服務(wù)器上使用的任何后端語言。

混合應(yīng)用的劣勢

當然,如果混合應(yīng)用沒有缺點,沒人想開發(fā)原生應(yīng)用。現(xiàn)實中顯然不是這種情況,并且這里有幾個原因解釋了為什么會這樣。概括來說,混合應(yīng)用較慢,較臃腫,外觀看起來沒有原生的感覺,并且,最重要的是,沒有原生的體驗。

Nitro的缺失

Nitro是移動Safari的Javascript引擎,速度太TMD快了。不幸的是,由于安全的關(guān)系,UIWebViews無法享受到這個速度提升帶來的優(yōu)勢:

Nitro 比WebKit之前的JavaScript引擎性能有所提升的最大原因是其采用了JIT-”Just-In-Time” 編譯… JIT需要可以把RAM中的內(nèi)存頁標記為可執(zhí)行狀態(tài)的能力,但是,iOS,出于安全的考量,不允許內(nèi)存頁被標記為可執(zhí)行狀態(tài)。這是一個重要并且嚴格的安全 策略。大部分現(xiàn)代操作系統(tǒng)允許內(nèi)存頁被標記為可執(zhí)行狀態(tài)-包括Mac OS X,Windows,和(我相信)Android。iOS 4.3對這個策略有個例外,但是這個例外只限于移動Safari。

實際上來說,這意味著如果你的混合應(yīng)用使用了Javascript,那么你將會感覺到同樣的UI要比在移動 Safari中要慢,也比以 Objective C實現(xiàn)的同樣的UI要慢。不幸的是,這兒沒有簡單的方法來解決這個問題,除了減少或者全部移除UIWebViews中你所使用的Javascript之 外,盡可能的以CSS3動畫(animations)和過渡(transitions)來做為替代(這可以利用GPU加速的優(yōu)勢)。

 

為了弄清楚,你可以只使用CSS3來完成一些真實的不可思議的效果,就像剛才Hakim El Hattab在他的stroll.js項目所演示的那樣。但是,總的來說,Nitro的缺失是任何混合iOS應(yīng)用成功的嚴重障礙,特別是如果想獲得與原生iOS應(yīng)用同樣的外觀和體驗。

模仿原生UI的挑戰(zhàn)

除了上面描述的性能問題之外,模仿原生Cocoa Touch用戶界面的挑戰(zhàn)是實現(xiàn)一個混合應(yīng)用所面對的另一個困難。就像之前被指出過無數(shù)次,iPhone應(yīng)用擁有非常不同尋常的外觀和體驗。比如,Table cell擁有標準的字體大小,內(nèi)邊距和空白要求,gradient selection高亮,disclosure箭頭,以及許多其他很難被復(fù)制的特性。

一個替代的方式是放棄對iOS系統(tǒng)控件的復(fù)制,相反為你的應(yīng)用構(gòu)建一個獨一無二的UI,就像Facebook的 News Feed和Timeline功能那樣。但是,即使你選擇了這個方法,為了使你的混合應(yīng)用在感覺上不像一個web頁面,這兒還有一些WebKit特性需要被 解決。

有時候事情很容易變糟

預(yù)計遲早有一天,你混合視圖中的CSS或者 Javascript文件將會加載失敗,這不是沒有理由的。可能你的用戶是紐約或者舊金山的 AT&T的客戶,眾所周知他們使用的是不穩(wěn)定的GSM網(wǎng)絡(luò)。可能上帝今天僅僅是沒對你笑而已。不管怎么樣,終有一天你將會給用戶展示一個像這樣的 UI:

…并且最糟糕的是你對于這種情況幾乎做不了任何事情,除了把你的JS和CSS都混入HTML頁面中。這種情況對于你和你的應(yīng)用都是極為糟糕的,并且它是完全無法控制的。至少對一個完整的原生應(yīng)用來說,服務(wù)端錯誤可以通過一個彈出的警告來更加優(yōu)雅的進行處理。 (截屏來自@timanrebel,社會化滑雪和滑雪板應(yīng)用,Snowciety的創(chuàng)始人。)

如何使你的混合應(yīng)用擁有原生的體驗UIWebView的陰影和背景顏色

默認情況下,UIWebViews會顯示一個陰影,以及背景顏色或者一個位于渲染頁面下面的圖案(取決于iOS版本和硬件)。這個外觀和感覺明顯是非原生 的,所以你將會需要移除它們兩個。幸運的是,這么做很簡單:為了使視圖變得扁平(flat),所有你需要做的事情就是一個UIWebView子類里邊的幾 行代碼。check out我的那個MIT協(xié)議的項目,F(xiàn)latWebView,看看例子里邊是如何做的。

鏈接的高亮顯示

為了幫助用戶知道他們究竟觸碰過哪里,當鏈接被觸碰的時候WebKit會在其周圍高亮的顯示一個半透明的矩形。

盡管這對于web來說很便捷,但是它在感覺上明顯不是原生的。為了清除這個行為,你可以在你的web應(yīng)用中包含這個CSS片段:

  1. /*http://stackoverflow.com/questions/9157080/wrong-webkit-tap-highlight-color-behavior-when-page-as-web-standalone-app */  
  2.   
  3. html {  
  4.     -webkit-tap-highlight-color: rgba(0,0,0,0);  
  5.     -webkit-user-select: none;  

觸摸延遲

默認情況下,當 WebKit對web頁面上的被觸摸的鏈接進行響應(yīng)的時候,它會增加一個大約300毫秒的延遲。這實際上是一個特性,不是一個 bug,因為意外觸碰一個web頁面上的錯誤鏈接是特別常見的,所以擁有一個細微的延遲可以給用戶提供一個修正他們錯誤的機會,對于什么都不做來說這可以 創(chuàng)造更好的體驗。無論如何,當你正在創(chuàng)建一個混合應(yīng)用的時候,你應(yīng)該只使用觸碰目標(hit target)尺寸大得可以避免被意外觸碰的UI組件。(你正在使用最小尺寸為40×40px的大尺寸觸碰目標,對嗎?)

為了確保你應(yīng)用的UI在感覺上和Cocoa Touch的UI擁有一樣的響應(yīng)體驗,當你在創(chuàng)建一個混合應(yīng)用的時候你必須禁用WebKit的觸摸延遲的特性。Matteo Spinelli提供了一些方便的Javascript代碼(不是jQuery!)用來解決這個「問題」:Remove onclick delay on Webkit for iPhone.

滾動

過去創(chuàng)建一個混合應(yīng)用最大的挑戰(zhàn)之一就是在一個UIWebView中復(fù)制原 生的滾動行為。特別是想要在UIWebView中的UIScrollView子類中去復(fù)制滾動速度,慣性以及「橡皮筋」(rubberbanding)視 覺效果,這幾乎是不可能。幸運的是,蘋果在iOS 5中為UIWebView增加了一個scrollView屬性,這使得對上面這些功能的支持是小菜一碟。

你所需要做的就是把你web視圖上的滾動視圖的decelerationRate屬性設(shè)置為UIScrollViewDecelerationRateNormal:

  1. UIWebView *hybridView = [self somethingThatGetsOurWebView]; 
  2. webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal; 

Objective C到Javascript

為了在原生代碼發(fā)生改變的時候去更新一個web視圖,你擁有三個選擇:

  • 重新加載UIWebView的內(nèi)容。
  • 使用NSURLRequest加載一個新頁面。
  • 在你的UIWebView中使用-stringByEvaluatingJavaScriptFromString:這個API來執(zhí)行Javascript代碼。

重新加載@UIWebView@中的內(nèi)容-或者加載一個全新的頁面-這糟透了,因為這將會在一個無法忽視的時間內(nèi)展示給你一個空白,無法操作的頁面。你可以一直顯示一個loading HUD視圖(比如SVProgressHUD),但是這仍然不是一個非常好的體驗。

在UIWebView中執(zhí)行Javascript代碼來更新視圖是一個較好的選擇:比如,這給你提供了執(zhí)行部分更新的機會。不過,它也有它自己的挑戰(zhàn),比如極其糟糕的調(diào)試體驗,當一些功能不能正常工作的時候你就會感受到了。

Javascript到Objective C

為了在當你的web視圖發(fā)生改變 的時候去更新原生代碼,與iOS打賭(譯者:交互)的最佳方式是實現(xiàn)UIWebView的委托方法 -webView:shouldStartLoadWithRequest:navigationType:。為了可以從UIWebView中調(diào)用原生平 臺的特性,你可以定義自己的scheme(比如用myappname://代替http://)和自己的URIs(比如用 showImageCapture代替apple.com)。不幸的是,這個方案即使對于復(fù)雜程度不高的應(yīng)用來說也會退化為一個龐大的if區(qū)塊。

比如說Facebook可能像這樣來實現(xiàn)他們的委托方法:

  1. if ([request.url.scheme isEqual:@"showImagePicker"]) {  
  2.     // show a UIImagePickerController  
  3. else if ([request.url.scheme isEqual:@"sendMessage"]) {  
  4.     // show the send message view controller  
  5. else if ([request.url.scheme isEqual:@"checkIn"]) {  
  6.     // show the places checkin view controller  
  7. else if ([request.url.scheme isEqual:@"postStatus"]) {  
  8.     // show the post status view controller  

幸運的是,這里有一些方法可以簡化它。比如,你可以在某種點對點的調(diào)度系統(tǒng)中使用一個NSDictionary來對scheme到action進行路由。

  1. - (void)viewDidLoad 
  2.     self.dispatch = [NSMutableDictionary dictionary]; 
  3.     [dispatch setObject:[NSValue valueWithPointer:@selector(showImagePickerForURL:)] forKey:@"showImagePicker"]; 
  4.   
  5. - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 
  6.     NSValue *selectorPointer = [self.dispatch objectForKey:request.url.scheme]; 
  7.     if (selectorPointer) 
  8.     { 
  9.       [self performSelector:[selectorPointer pointerValue] withObject:request.url]; 
  10.       return NO; 
  11.     } 
  12.     else 
  13.     { 
  14.       return YES; 
  15.     } 

Facebook

當Facebook的iPhone應(yīng)用首次亮相的時候,它幾乎是個完整的原生應(yīng)用,是由Joe Hewitt單槍匹馬寫出來的(據(jù)我所知),他把Three20 iOS框架從應(yīng)用的核心中提取了出來。如果你曾經(jīng)用Three20開發(fā)過應(yīng)用,你知道這個框架有一點笨拙。可能,在Joe退出iOS開發(fā)團隊之后的一段時間,F(xiàn)acebook的領(lǐng)導(dǎo)們判斷出當前應(yīng)用的實現(xiàn)簡直是太難維護了,是時候重新考慮方案了。

Dave Fetterman,F(xiàn)acebook平臺的工程經(jīng)理,他在去年F8大會一個演講中的部分篇幅描述了這個突變:

由于一些根本原因你需要為四個不同的平臺開發(fā)應(yīng)用。什么?你想為所有的這些平臺各自開發(fā)?好吧,那你將會像SB一樣開發(fā)四次。然后每個平臺上都有了所有的特性-群組,交易,新的profile。但是這么做實在是太遭了。這么說來,我們不得不開發(fā)四次,這意味著開發(fā)的速度變慢了。代碼也變得陳 舊了。這里會存在不能一起工作的不同版本的等價功能,這對于像Facebook這樣快速發(fā)展的公司來說太糟糕了。

所以,當Facebook4.0的iOS版本發(fā)布的時候, 它體現(xiàn)出了”Write Once, Run Anywhere”的思想。就個人來講,我必須說,我認為在理論上這是一個偉大的想法。沒人想開發(fā)和維護相同的功能集合四次,特別是像Facebook這 樣的公司,它擁有驚人的高「用戶-工程師」比例。很不幸,真實的情況是UIWebView并沒有足夠的能力來處理像Facebook這樣的富應(yīng)用的需求, 用戶的眼睛是雪亮的:

總結(jié)

綜上所述,混合應(yīng)用在iOS上的體驗不太好:它們較慢,也較笨拙,可能引起一些無法修復(fù)的錯 誤,并且它們在感覺上并不能和原生應(yīng)用相比。但是,它們 所提供一些優(yōu)勢在特殊的境況之下,可能是一個有價值的折中方案。個人來講,我建議你應(yīng)該一直用原生代碼來開發(fā)你整個iOS應(yīng)用的用戶界面,然后根據(jù)需求所 要求的那樣有選擇的把應(yīng)用中的部分功能改造成混合方式,不管需求是純開發(fā)速度,即刻更新的能力,或者在很短的時間內(nèi)在用戶身上去測試功能的多個變化。

最后,無論怎樣,對你的用戶和你的業(yè)務(wù)來說,只有你知道什么才是真正正確的。確保你是因為正確的原因而做的選擇,而不是純粹的圖方便。

對于混合應(yīng)用你是怎么看的?什么時候你覺得利大于弊?你還有其他可以提高混合應(yīng)用體驗的竅門和技巧嗎?還需要更多如何從混合開發(fā)轉(zhuǎn)向完全原生開發(fā)的建議?請留言,我們期望聽到你對這個問題的聲音。

責(zé)任編輯:閆佳明 來源: w3cfuns
相關(guān)推薦

2014-12-25 16:07:32

DHH混合移動應(yīng)用Hybrid App

2014-12-17 10:29:59

混合應(yīng)用Hybrid App開發(fā)實戰(zhàn)

2022-11-04 14:58:59

應(yīng)用開發(fā)鴻蒙

2019-02-25 14:23:18

微軟安卓iOS

2014-04-09 14:02:21

混合云應(yīng)用混合云

2011-05-11 10:02:37

iOS

2022-03-15 08:00:00

Flutter開發(fā)工具

2015-03-30 14:34:08

混合云應(yīng)用開發(fā)混合云部署

2016-01-04 09:24:51

混合云平臺現(xiàn)代應(yīng)用開發(fā)混合云開發(fā)

2009-03-11 13:18:57

Android入門Android開發(fā)Android模擬器

2011-07-08 14:58:16

iPhone Xcode iOS

2020-12-25 10:52:28

鴻蒙HarmonyOS應(yīng)用開發(fā)

2011-08-11 16:50:04

iOSTwitter

2013-01-24 09:16:23

移動開發(fā)者移動應(yīng)用開發(fā)

2011-06-24 16:19:59

QT web Webkit

2011-06-03 14:36:32

IOS 環(huán)境搭建

2011-06-03 15:36:22

IOS 環(huán)境搭建

2011-06-03 15:08:09

IOS 環(huán)境搭建

2011-06-03 16:05:20

IOS 環(huán)境搭建

2010-10-15 09:39:22

MeeGoQt
點贊
收藏

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

主站蜘蛛池模板: 国产日韩欧美精品一区二区三区 | 日韩精品 电影一区 亚洲 | 一道本一区二区 | 国产亚洲一区二区三区在线观看 | 黄色网址在线免费观看 | 精精精精xxxx免费视频 | 精品在线视频播放 | 成人精品鲁一区一区二区 | 日韩精品在线免费观看视频 | 欧美成人精品一区 | www..com18午夜观看 | 欧美99久久精品乱码影视 | 国产真实乱对白精彩久久小说 | 99国产精品99久久久久久粉嫩 | 激情小说综合网 | 黑人久久久 | 亚洲视频三区 | 中文字幕电影在线观看 | 伊人久久综合 | 免费三级网站 | 91看片免费版 | 国产精品久久久久久久 | 亚洲一区视频在线播放 | 亚洲激情一区二区三区 | 亚洲精品视 | 日本一区二区三区四区 | 成人福利在线 | 国产成人在线视频免费观看 | 久久久成人动漫 | 国产精品成人一区二区三区 | 狠狠爱免费视频 | 91精品国产综合久久福利软件 | 夜夜艹| 亚洲天堂成人在线视频 | 精品在线免费观看视频 | 国产区第一页 | 日操夜操 | 日韩免费毛片视频 | 国产91久久久久蜜臀青青天草二 | 色黄爽 | www.av在线|