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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android:异步处理之Handler+Thread的应用(一)

發(fā)布時間:2023/12/18 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android:异步处理之Handler+Thread的应用(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

  很久很久以前就聽說了,每一個android的應(yīng)用程序都會分別運行在一個獨立的dalvik虛擬機(jī)進(jìn)程中,而在每個虛擬機(jī)在啟動時會運行一個UI主線程(Main Thread),而為啥叫UI主線程而不是AI主線程或者是BI主線程呢?因為它要處理全部和UI相關(guān)的事件;因為Android系統(tǒng)采用的是UI單線程模型,只能由UI主線程對其進(jìn)行UI操作,如果子線程抱著眾人拾柴火焰高的覺悟來幫忙UI主線程更新UI界面的話,對不起哦~Android系統(tǒng)就會報錯的。粗俗點講就是:我們只能通過UI主線程來蹂躪UI界面,但是其他線程來的話會被告弓雖女干滴。。

  那么現(xiàn)在問題來了!鑒于近來挖掘機(jī)那么火,我也不好意思繼續(xù)問這個問題了。。。嗯嗯~網(wǎng)絡(luò)操作之類耗時操作就像挖掘機(jī)那樣,我們在下載文件的時候一樣跟挖掘機(jī)挖個大坑一樣需要一定的時間;當(dāng)挖掘機(jī)司機(jī)挖好一個大坑要找老板反饋工作完成一樣,我們下載好一個文件自然要馬上告訴屏幕前苦逼等待的用戶們,誰知道他們多著急想看**.avi呢;但是你在挖坑時好意思叫老板在旁邊看你嗎?老板分分鐘為幾千萬上下的事忙著呢~所以嘛同理,對于網(wǎng)絡(luò)操作,我們當(dāng)然也不能在UI主線程中進(jìn)行網(wǎng)絡(luò)操作,因為這樣會阻塞主線程造成界面卡死,也會造成ANR(應(yīng)用程序無響應(yīng))。我們應(yīng)該把文件下載、文件讀取諸如此類的耗時操作放到子線程中去進(jìn)行,等到子線程耗時操作完成時通知UI界面做出響應(yīng)。

不要在UI主線程中進(jìn)行耗時操作

  如果你不信邪一定要在UI主線程進(jìn)行下載文件、加載大文件之類的耗時操作。如下代碼:

private Button btn; //onCreate之類的生命周期的方法就是允許在UI主線程中 @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = (Button) findViewById(R.id.btn);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {downLoad();//調(diào)用UI主線程的下載函數(shù)}}); }private void downLoad(){try {Thread.sleep(10000);//休眠10秒,模擬網(wǎng)絡(luò)文件下載耗時操作} catch (InterruptedException e) {e.printStackTrace();} }

你會發(fā)現(xiàn)界面卡主了10秒:(模擬下載操作的按鈕為深色,說明按鈕一直為按下狀態(tài))

如果這時候你手比較管不住的話,雖然點幾下界面,沒事~Androi系統(tǒng)會馬上送你一份ANR大禮哦,而且還不用998元耶!

小結(jié)一個:不要在UI主線程中進(jìn)行耗時操作,你可能會疑問什么是UI主線程,UI主線程主要運行的就是Activity、Service等里面的生命周期方法,所以不要在生命周期方法如onCreate()中進(jìn)行下載這些大事件。對于耗時操作,我們應(yīng)該新建一個子線程并交給他處理,但是還需要注意一點。

不要在子線程中更新UI界面

  既然我們說下載文件要在子線程中進(jìn)行,那么我們就新建一個子線程把下載操作放到里面進(jìn)行咯,代碼如下:

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = (Button) findViewById(R.id.btn);text = (TextView) findViewById(R.id.text);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {new Thread(){@Overridepublic void run() {//在子線程中進(jìn)行下載操作try {Thread.sleep(10000);//休眠10秒,模擬耗時操作} catch (InterruptedException e) {e.printStackTrace();}text.setText("下載完成");//設(shè)置TextView,通知UI界面下載完成}}.start();}}); }

10秒后,你覺得會在UI界面完美顯示“下載完成”么?一般,出現(xiàn)這個才符合Androi系統(tǒng)的一貫作風(fēng)

并且在Log中報錯如下

小弟英語其實很廢柴,但是隱隱約約有人告訴我:這不是叫只能在主線程中更新UI嗎?不信,金山翻譯一下去呀。。。。

小結(jié)一個:不要在子線程中更新UI界面,這樣會導(dǎo)致android系統(tǒng)報錯、應(yīng)用崩潰退出。UI界面時單線程模式,我們只能通過UI主線程中對UI的界面進(jìn)行相關(guān)的更新,千萬不要越線辦事,你要記住的是~UI界面是UI主線程的老婆,你們這些子線程誰都別想動!

利用Thread+Handler進(jìn)行異步處理

  那么問題來了,現(xiàn)在我們需要進(jìn)行耗時操作(例如下載文件)時不能在主線程執(zhí)行,我們又需要在UI界面通知用戶我們活干完了不能再子線程中執(zhí)行。這似乎是一個棘手的熱山芋呀,幸好谷歌給我們提供了一個救我們于危難之中的Handler,一個能讓主線程監(jiān)聽子線程發(fā)送來消息的東東,至于Handler的實現(xiàn)原理我會在后面的文章詳細(xì)介紹,現(xiàn)在我們只需要先了解Handler的用法。

private Button btn; private TextView text;private Handler handler = new Handler(){private int process = 0;@Overridepublic void handleMessage(Message msg) {switch(msg.what){case 0://更細(xì)下載進(jìn)度process += 1;text.setText("下載" + process + "%");//在主線程中更新UI界面break;case 1://提示下載完成text.setText("下載完成");//在主線程中更新UI界面break;default:break;}} }; //onCreate之類的生命周期的方法就是允許在UI主線程中 @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn = (Button) findViewById(R.id.btn);text = (TextView) findViewById(R.id.text);btn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {new Thread(){@Overridepublic void run() {//在子線程中進(jìn)行下載操作for(int i = 0; i < 100; i++){try {Thread.sleep(200);//休眠0.2秒,模擬耗時操作} catch (InterruptedException e) {e.printStackTrace();}handler.sendEmptyMessage(0);//發(fā)送消息到handler,通知下載進(jìn)度}handler.sendEmptyMessage(1);//發(fā)送消失到handler,通知主線程下載完成}}.start();}}); }

?這里來解釋一下Handler的使用方法:

1、我們?yōu)榱瞬蛔枞骶€程,將下載任務(wù)通過子線程來執(zhí)行。

new Thread(){@Overridepublic void run() {//在子線程中進(jìn)行下載操作for(int i = 0; i < 100; i++){try {Thread.sleep(200);//休眠0.2秒,模擬耗時操作} catch (InterruptedException e) {e.printStackTrace();}handler.sendEmptyMessage(0);//發(fā)送消息到handler,通知下載進(jìn)度}handler.sendEmptyMessage(1);//發(fā)送消失到handler,通知主線程下載完成} }.start();

2、當(dāng)子線程需要跟主線程交流時,也就是當(dāng)子線程要跟UI主線程說:親,偶下載文件到80%了或者偶已經(jīng)把文件下載完成了!執(zhí)行這句代碼

handler.sendEmptyMessage(1);//發(fā)送消失到handler,通知主線程下載完成

3、當(dāng)發(fā)送空消息之后,在Handler將會收到子線程發(fā)來的消息,觸發(fā)回調(diào)方法handlerMessage(),我們就在這里對UI界面進(jìn)行更新,這個回調(diào)方法是運行在UI主線程的

@Override public void handleMessage(Message msg) {switch(msg.what){case 0://更細(xì)下載進(jìn)度process += 1;text.setText("下載" + process + "%");//在主線程中更新UI界面break;case 1://提示下載完成text.setText("下載完成");//在主線程中更新UI界面break;default:break;} }

4、最后,UI界面更新成功!(圖嘛,我這里就不上了。。。。)

小結(jié)一個:對于比較耗時間的任務(wù),我們一般需要放在子線程中執(zhí)行;當(dāng)子線程更新UI界面時,子線程可以通過Handler來通知主線程更新,一般通過發(fā)送消息來觸發(fā)handlerMessage()這個回調(diào)方法來執(zhí)行UI界面的更新。

進(jìn)一步簡略de操作:handler.post方法和view.post方法

  但是如果你覺得每次都要重寫handlerMessage()比較麻煩,我們完全可以用更加簡略的方法來解決我們的需求,就是用handler中的post方法。代碼如下

new Thread(){@Overridepublic void run() {//在子線程中進(jìn)行下載操作try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}handler.post(new Runnable() {@Overridepublic void run() {text.setText("下載完成");}});//發(fā)送消失到handler,通知主線程下載完成} }.start();

  這樣處理的話我們就可以不用重寫handlerMessage()方法了,適合子線程與主線程進(jìn)行較為單一的交流。但在這里我們要強(qiáng)調(diào)的一點的是,post里面的Runnable還是在UI主線程中運行的,而不會另外開啟線程運行,千萬不要在Runnable的run()里面進(jìn)行耗時任務(wù),不然到時又ANR了可別找我哦。。

如果你有時候連handler都不想搞,還可以這樣寫代碼滴。

我們只需要把handler換成View組件進(jìn)行post,更新任務(wù)自然會加載到UI主線程中進(jìn)行處理。

text.post(new Runnable() {@Overridepublic void run() {text.setText("下載完成");} });//發(fā)送消失到handler,通知主線程下載完成

至于Handler機(jī)制以及這兩種post的原理,我將會在后面的博客文章中專題介紹,這里只提供一個使用方法而已。

?

終于寫完了睡覺,怎么沒有掌聲呢??雞蛋、啤酒瓶砸?guī)讉€上來~~~~哈哈

權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。 https://blog.csdn.net/fnhfire_7030/article/details/79518819前言:又到了一年一度的跳槽季,準(zhǔn)備跳槽的你在關(guān)于Android面試方面的知識都完全掌握了嗎?Android面試中經(jīng)常被問到的知識——Android消息機(jī)制即Handler有關(guān)的問題你都能解釋的清楚嗎?如果你對Android消息機(jī)制比較模糊或者能夠回答與Handler有關(guān)的問題但是不清楚其中的原理,那么你將會在本文得到你想要的答案。
閱讀本文后的收貨??閱讀本文后你將會有以下收獲:
清楚的理解Handler的工作原理理清Handler、Message、MessageQueue以及Looper之間的關(guān)系知道Looper是怎么和當(dāng)前線程進(jìn)行綁定的是否能在子線程中創(chuàng)建Handler獲得分析Handler源碼的思路要想有以上的收獲,就需要研究Handler的源碼,從源碼中來得到答案。
開始探索之路Handler的使用??先從Handler的使用開始。我們都知道Android的主線程不能處理耗時的任務(wù),否者會導(dǎo)致ANR的出現(xiàn),但是界面的更新又必須要在主線程中進(jìn)行,這樣,我們就必須在子線程中處理耗時的任務(wù),然后在主線程中更新UI。但是,我們怎么知道子線程中的任務(wù)何時完成,又應(yīng)該什么時候更新UI,又更新什么內(nèi)容呢?為了解決這個問題,Android為我們提供了一個消息機(jī)制即Handler。下面就看下Handler的常見使用方式,代碼如下
public class MainActivity extends AppCompatActivity implements View.OnClickListener {? ? private Button mStartTask;
? ? @SuppressLint("HandlerLeak")? ? private Handler mHandler = new Handler() {? ? ? ? @Override? ? ? ? public void handleMessage(Message msg) {? ? ? ? ? ? super.handleMessage(msg);? ? ? ? ? ? if (msg.what == 1) {? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "刷新UI、", Toast.LENGTH_SHORT).show();? ? ? ? ? ? }? ? ? ? }? ? };
? ? @Override? ? protected void onCreate(Bundle savedInstanceState) {? ? ? ? super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);? ? ? ? initView();? ? }
? ? private void initView() {? ? ? ? mStartTask = findViewById(R.id.btn_start_task);? ? ? ? mStartTask.setOnClickListener(this);? ? }
? ? @Override? ? public void onClick(View v) {? ? ? ? switch (v.getId()) {? ? ? ? ? ? case R.id.btn_start_task:? ? ? ? ? ? ? ? new Thread(new Runnable() {? ? ? ? ? ? ? ? ? ? @Override? ? ? ? ? ? ? ? ? ? public void run() {? ? ? ? ? ? ? ? ? ? ? ? try {? ? ? ? ? ? ? ? ? ? ? ? ? ? Thread.sleep(1000);? ? ? ? ? ? ? ? ? ? ? ? ? ? mHandler.sendEmptyMessage(1);? ? ? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) {? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }).start();? ? ? ? ? ? ? ? break;? ? ? ? }? ? }}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546可以看到在子線程中,讓線程睡了一秒,來模仿耗時的任務(wù),當(dāng)耗時任務(wù)處理完之后,Handler會發(fā)送一個消息,然后我們可以在Handler的handleMessage方法中得到這個消息,得到消息之后就能夠在handleMessage方法中更新UI了,因為handleMessage是在主線程中嘛。到這里就會有以下疑問了:
Handler明明是在子線程中發(fā)的消息怎么會跑到主線程中了呢?Handler的發(fā)送消息handleMessage又是怎么接收到的呢?帶著這兩個疑問,開始分析Handler的源碼。
Handler的源碼分析??先看下在我們實例化Handler的時候,Handler的構(gòu)造方法中都做了那些事情,看代碼
final Looper mLooper;? ? final MessageQueue mQueue;? ? final Callback mCallback;? ? final boolean mAsynchronous;
/**? ? ?* Default constructor associates this handler with the {@link Looper} for the? ? ?* current thread.? ? ?*? ? ?* If this thread does not have a looper, this handler won't be able to receive messages? ? ?* so an exception is thrown.? ? ?*/? ? public Handler() {? ? ? ? this(null, false);? ? }
/**? ? ?* Use the {@link Looper} for the current thread with the specified callback interface? ? ?* and set whether the handler should be asynchronous.? ? ?*? ? ?* Handlers are synchronous by default unless this constructor is used to make? ? ?* one that is strictly asynchronous.? ? ?*? ? ?* Asynchronous messages represent interrupts or events that do not require global ordering? ? ?* with respect to synchronous messages.? Asynchronous messages are not subject to? ? ?* the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}.? ? ?*? ? ?* @param callback The callback interface in which to handle messages, or null.? ? ?* @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for? ? ?* each {@link Message} that is sent to it or {@link Runnable} that is posted to it.? ? ?*? ? ?* @hide? ? ?*/? ? public Handler(Callback callback, boolean async) {? ? ? ? if (FIND_POTENTIAL_LEAKS) {? ? ? ? ? ? final Class<? extends Handler> klass = getClass();? ? ? ? ? ? if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&? ? ? ? ? ? ? ? ? ? (klass.getModifiers() & Modifier.STATIC) == 0) {? ? ? ? ? ? ? ? Log.w(TAG, "The following Handler class should be static or leaks might occur: " +? ? ? ? ? ? ? ? ? ? klass.getCanonicalName());? ? ? ? ? ? }? ? ? ? }
? ? ? ? mLooper = Looper.myLooper();? ? ? ? if (mLooper == null) {? ? ? ? ? ? throw new RuntimeException(? ? ? ? ? ? ? ? "Can't create handler inside thread that has not called Looper.prepare()");? ? ? ? }? ? ? ? mQueue = mLooper.mQueue;? ? ? ? mCallback = callback;? ? ? ? mAsynchronous = async;? ? }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152通過源碼可以看到Handler的無參構(gòu)造函數(shù)調(diào)用了兩個參數(shù)的構(gòu)造函數(shù),而在兩個參數(shù)的構(gòu)造函數(shù)中就是將一些變量進(jìn)行賦值。
??看下下面的代碼
?mLooper = Looper.myLooper();? ? ? ? if (mLooper == null) {? ? ? ? ? ? throw new RuntimeException(? ? ? ? ? ? ? ? "Can't create handler inside thread that has not called Looper.prepare()");? ? ? ? }12345這里是通過Looper中的myLooper方法來獲得Looper實例的,如果Looper為null的話就會拋異常,拋出的異常內(nèi)容翻譯過來就是
無法在未調(diào)用Looper.prepare()的線程內(nèi)創(chuàng)建handler
從這句話中,我們可以知道,在調(diào)用Looper.myLooper()之前必須要先調(diào)用Looper.prepare()方法,現(xiàn)在來看下prepare方法中的內(nèi)容,如下
?/** Initialize the current thread as a looper.? ? ? * This gives you a chance to create handlers that then reference? ? ? * this looper, before actually starting the loop. Be sure to call? ? ? * {@link #loop()} after calling this method, and end it by calling? ? ? * {@link #quit()}.? ? ? */? ? public static void prepare() {? ? ? ? prepare(true);? ? }
? ? private static void prepare(boolean quitAllowed) {? ? ? ? if (sThreadLocal.get() != null) {? ? ? ? ? ? throw new RuntimeException("Only one Looper may be created per thread");? ? ? ? }? ? ? ? sThreadLocal.set(new Looper(quitAllowed));? ? }12345678910111213141516從上面代碼中可以看到,prepare()方法調(diào)用了prepare(boolean quitAllowed)方法,prepare(boolean quitAllowed) 方法中則是實例化了一個Looper,然后將Looper設(shè)置進(jìn)sThreadLocal中,到了這里就有必要了解一下ThreadLocalle。
什么是ThreadLocalThreadLocal 為解決多線程程序的并發(fā)問題提供了一種新的思路。使用這個工具類可以很簡潔地編寫出優(yōu)美的多線程程序。當(dāng)使用ThreadLocal 維護(hù)變量時,ThreadLocal 為每個使用該變量的線程提供獨立的變量副本,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應(yīng)的副本。
如果看完上面這段話還是搞不明白ThreadLocal有什么用,那么可以看下下面代碼運行的結(jié)果,相信看下結(jié)果你就會明白ThreadLocal有什么作用了。
public class MainActivity extends AppCompatActivity {? ??? ? private static final String TAG = "MainActivity";? ? private ThreadLocal<Integer> mThreadLocal = new ThreadLocal<>();? ??? ? @SuppressLint("HandlerLeak")? ? private Handler mHandler = new Handler(){? ? ? ? @Override? ? ? ? public void handleMessage(Message msg) {? ? ? ? ? ? super.handleMessage(msg);? ? ? ? ? ? if (msg.what == 1) {? ? ? ? ? ? ? ? Log.d(TAG, "onCreate: "+mThreadLocal.get());? ? ? ? ? ? }? ? ? ? }? ? };
? ? @Override? ? protected void onCreate(Bundle savedInstanceState) {? ? ? ? super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);? ? ? ? mThreadLocal.set(5);
? ? ? ? Thread1 thread1 = new Thread1();? ? ? ? thread1.start();
? ? ? ? Thread2 thread2 = new Thread2();? ? ? ? thread2.start();
? ? ? ? Thread3 thread3 = new Thread3();? ? ? ? thread3.start();
? ? ? ? new Thread(new Runnable() {? ? ? ? ? ? @Override? ? ? ? ? ? public void run() {? ? ? ? ? ? ? ? try {? ? ? ? ? ? ? ? ? ? Thread.sleep(2000);? ? ? ? ? ? ? ? ? ? mHandler.sendEmptyMessage(1);? ? ? ? ? ? ? ? } catch (InterruptedException e) {? ? ? ? ? ? ? ? ? ? e.printStackTrace();? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? }).start();? ? }
? ? class Thread1 extends Thread {
? ? ? ? @Override? ? ? ? public void run() {? ? ? ? ? ? super.run();? ? ? ? ? ? mThreadLocal.set(1);? ? ? ? ? ? Log.d(TAG, "mThreadLocal1: "+ mThreadLocal.get());? ? ? ? }? ? }
? ? class Thread2 extends Thread {
? ? ? ? @Override? ? ? ? public void run() {? ? ? ? ? ? super.run();? ? ? ? ? ? mThreadLocal.set(2);? ? ? ? ? ? Log.d(TAG, "mThreadLocal2: "+ mThreadLocal.get());? ? ? ? }? ? }
? ? class Thread3 extends Thread {
? ? ? ? @Override? ? ? ? public void run() {? ? ? ? ? ? super.run();? ? ? ? ? ? mThreadLocal.set(3);? ? ? ? ? ? Log.d(TAG, "mThreadLocal3: "+ mThreadLocal.get());? ? ? ? }? ? }}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475看下這段代碼運行之后打印的log


可以看到雖然在不同的線程中對同一個mThreadLocal中的值進(jìn)行了更改,但最后仍可以正確拿到當(dāng)前線程中mThreadLocal中的值。由此我們可以得出結(jié)論ThreadLocal.set方法設(shè)置的值是與當(dāng)前線程進(jìn)行綁定了的。
??知道了ThreadLocal.set方法的作用,則Looper.prepare方法就是將Looper與當(dāng)前線程進(jìn)行綁定(當(dāng)前線程就是調(diào)用Looper.prepare方法的線程)。
??文章到了這里我們可以知道以下幾點信息了
在對Handler進(jìn)行實例化的時候,會對一些變量進(jìn)行賦值。對Looper進(jìn)行賦值是通過Looper.myLooper方法,但在調(diào)用這句代碼之前必須已經(jīng)調(diào)用了Looper.prepare方法。Looper.prepare方法的作用就是將實例化的Looper與當(dāng)前的線程進(jìn)行綁定。這里就又出現(xiàn)了一個問題:在調(diào)用Looper.myLooper方法之前必須必須已經(jīng)調(diào)用了Looper.prepare方法,即在實例化Handler之前就要調(diào)用Looper.prepare方法,但是我們平常在主線程中使用Handler的時候并沒有調(diào)用Looper.prepare方法呀!這是怎么回事呢?
??其實,在主線程中Android系統(tǒng)已經(jīng)幫我們調(diào)用了Looper.prepare方法,可以看下ActivityThread類中的main方法,代碼如下
?public static void main(String[] args) {? ? ? ? Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
? ? ? ? // CloseGuard defaults to true and can be quite spammy.? We? ? ? ? // disable it here, but selectively enable it later (via? ? ? ? // StrictMode) on debug builds, but using DropBox, not logs.? ? ? ? CloseGuard.setEnabled(false);
? ? ? ? Environment.initForCurrentUser();
? ? ? ? // Set the reporter for event logging in libcore? ? ? ? EventLogger.setReporter(new EventLoggingReporter());
? ? ? ? // Make sure TrustedCertificateStore looks in the right place for CA certificates? ? ? ? final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());? ? ? ? TrustedCertificateStore.setDefaultUserDirectory(configDir);
? ? ? ? Process.setArgV0("<pre-initialized>");
? ? ? ? Looper.prepareMainLooper();
? ? ? ? ActivityThread thread = new ActivityThread();? ? ? ? thread.attach(false);
? ? ? ? if (sMainThreadHandler == null) {? ? ? ? ? ? sMainThreadHandler = thread.getHandler();? ? ? ? }
? ? ? ? if (false) {? ? ? ? ? ? Looper.myLooper().setMessageLogging(new? ? ? ? ? ? ? ? ? ? LogPrinter(Log.DEBUG, "ActivityThread"));? ? ? ? }
? ? ? ? // End of event ActivityThreadMain.? ? ? ? Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);? ? ? ? Looper.loop();
? ? ? ? throw new RuntimeException("Main thread loop unexpectedly exited");? ? }123456789101112131415161718192021222324252627282930313233343536373839上面的代碼中有一句
Looper.prepareMainLooper();1這句話的實質(zhì)就是調(diào)用了Looper的prepare方法,代碼如下
?public static void prepareMainLooper() {? ? ? ? prepare(false);//這里調(diào)用了prepare方法? ? ? ? synchronized (Looper.class) {? ? ? ? ? ? if (sMainLooper != null) {? ? ? ? ? ? ? ? throw new IllegalStateException("The main Looper has already been prepared.");? ? ? ? ? ? }? ? ? ? ? ? sMainLooper = myLooper();? ? ? ? }? ? }123456789到這里就解決了,為什么我們在主線程中使用Handler之前沒有調(diào)用Looper.prepare方法的問題了。
??讓我們再回到Handler的構(gòu)造方法中,看下
mLooper = Looper.myLooper();1myLooper()方法中代碼如下
/**? ? ?* Return the Looper object associated with the current thread.? Returns? ? ?* null if the calling thread is not associated with a Looper.? ? ?*/? ? public static @Nullable Looper myLooper() {? ? ? ? return sThreadLocal.get();? ? }1234567其實就是從當(dāng)前線程中的ThreadLocal中取出Looper實例。
??再看下Handler的構(gòu)造方法中的
mQueue = mLooper.mQueue;1這句代碼。這句代碼就是拿到Looper中的mQueue這個成員變量,然后再賦值給Handler中的mQueue,下面看下Looper中的代碼
?final MessageQueue mQueue;? ??private Looper(boolean quitAllowed) {? ? ? ? mQueue = new MessageQueue(quitAllowed);? ? ? ? mThread = Thread.currentThread();? ? }123456同過上面的代碼,我們可以知道m(xù)Queue就是MessageQueue,在我們調(diào)用Looper.prepare方法時就將mQueue實例化了。
Handler的sendMessage方法都做了什么??還記得文章開始時的兩個問題嗎?
Handler明明是在子線程中發(fā)的消息怎么會跑到主線程中了呢?Handler的發(fā)送消息handleMessage又是怎么接收到的呢?下面就分析一下Handler的sendMessage方法都做了什么,看代碼
public final boolean sendMessage(Message msg)? ? {? ? ? ? return sendMessageDelayed(msg, 0);? ? }
public final boolean sendMessageDelayed(Message msg, long delayMillis)? ? {? ? ? ? if (delayMillis < 0) {? ? ? ? ? ? delayMillis = 0;? ? ? ? }? ? ? ? return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);? ? }
/**? ? ?* Enqueue a message into the message queue after all pending messages? ? ?* before the absolute time (in milliseconds) <var>uptimeMillis</var>.? ? ?* <b>The time-base is {@link android.os.SystemClock#uptimeMillis}.</b>? ? ?* Time spent in deep sleep will add an additional delay to execution.? ? ?* You will receive it in {@link #handleMessage}, in the thread attached? ? ?* to this handler.? ? ?*?? ? ?* @param uptimeMillis The absolute time at which the message should be? ? ?*? ? ? ? ?delivered, using the? ? ?*? ? ? ? ?{@link android.os.SystemClock#uptimeMillis} time-base.? ? ?*? ? ? ? ?? ? ?* @return Returns true if the message was successfully placed in to the?? ? ?*? ? ? ? ?message queue.? Returns false on failure, usually because the? ? ?*? ? ? ? ?looper processing the message queue is exiting.? Note that a? ? ?*? ? ? ? ?result of true does not mean the message will be processed -- if? ? ?*? ? ? ? ?the looper is quit before the delivery time of the message? ? ?*? ? ? ? ?occurs then the message will be dropped.? ? ?*/? ? public boolean sendMessageAtTime(Message msg, long uptimeMillis) {? ? ? ? MessageQueue queue = mQueue;? ? ? ? if (queue == null) {? ? ? ? ? ? RuntimeException e = new RuntimeException(? ? ? ? ? ? ? ? ? ? this + " sendMessageAtTime() called with no mQueue");? ? ? ? ? ? Log.w("Looper", e.getMessage(), e);? ? ? ? ? ? return false;? ? ? ? }? ? ? ? return enqueueMessage(queue, msg, uptimeMillis);? ? }123456789101112131415161718192021222324252627282930313233343536373839404142由上面的代碼可以看出,Handler的sendMessage方法最后調(diào)用了sendMessageAtTime這個方法,其實,無論時sendMessage、sendEmptyMessage等方法最終都是調(diào)用sendMessageAtTime。可以看到sendMessageAtTime這個方法最后返回的是*enqueueMessage(queue, msg, uptimeMillis);*下面看下這個方法,代碼如下
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {? ? ? ? msg.target = this;? ? ? ? if (mAsynchronous) {? ? ? ? ? ? msg.setAsynchronous(true);? ? ? ? }? ? ? ? return queue.enqueueMessage(msg, uptimeMillis);? ? }1234567這里有一句代碼非常重要,
?msg.target = this;1這句代碼就是將當(dāng)前的Handler賦值給了Message中的target變量。這樣,就將每個調(diào)用sendMessage方法的Handler與Message進(jìn)行了綁定。
enqueueMessage方法最后返回的是**queue.enqueueMessage(msg, uptimeMillis);**也就是調(diào)用了MessageQueue中的enqueueMessage方法,下面看下MessageQueue中的enqueueMessage方法,代碼如下
boolean enqueueMessage(Message msg, long when) {? ? ? ? if (msg.target == null) {? ? ? ? ? ? throw new IllegalArgumentException("Message must have a target.");? ? ? ? }? ? ? ? if (msg.isInUse()) {? ? ? ? ? ? throw new IllegalStateException(msg + " This message is already in use.");? ? ? ? }
? ? ? ? synchronized (this) {? ? ? ? ? ? if (mQuitting) {? ? ? ? ? ? ? ? IllegalStateException e = new IllegalStateException(? ? ? ? ? ? ? ? ? ? ? ? msg.target + " sending message to a Handler on a dead thread");? ? ? ? ? ? ? ? Log.w(TAG, e.getMessage(), e);? ? ? ? ? ? ? ? msg.recycle();? ? ? ? ? ? ? ? return false;? ? ? ? ? ? }
? ? ? ? ? ? msg.markInUse();? ? ? ? ? ? msg.when = when;? ? ? ? ? ? Message p = mMessages;? ? ? ? ? ? boolean needWake;? ? ? ? ? ? if (p == null || when == 0 || when < p.when) {? ? ? ? ? ? ? ? // New head, wake up the event queue if blocked.? ? ? ? ? ? ? ? msg.next = p;? ? ? ? ? ? ? ? mMessages = msg;? ? ? ? ? ? ? ? needWake = mBlocked;? ? ? ? ? ? } else {? ? ? ? ? ? ? ? // Inserted within the middle of the queue.? Usually we don't have to wake? ? ? ? ? ? ? ? // up the event queue unless there is a barrier at the head of the queue? ? ? ? ? ? ? ? // and the message is the earliest asynchronous message in the queue.? ? ? ? ? ? ? ? needWake = mBlocked && p.target == null && msg.isAsynchronous();? ? ? ? ? ? ? ? Message prev;? ? ? ? ? ? ? ? for (;;) {? ? ? ? ? ? ? ? ? ? prev = p;? ? ? ? ? ? ? ? ? ? p = p.next;? ? ? ? ? ? ? ? ? ? if (p == null || when < p.when) {? ? ? ? ? ? ? ? ? ? ? ? break;? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? if (needWake && p.isAsynchronous()) {? ? ? ? ? ? ? ? ? ? ? ? needWake = false;? ? ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ? msg.next = p; // invariant: p == prev.next? ? ? ? ? ? ? ? prev.next = msg;? ? ? ? ? ? }
? ? ? ? ? ? // We can assume mPtr != 0 because mQuitting is false.? ? ? ? ? ? if (needWake) {? ? ? ? ? ? ? ? nativeWake(mPtr);? ? ? ? ? ? }? ? ? ? }? ? ? ? return true;? ? }1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253上面的代碼就是將消息放進(jìn)消息隊列中,如果消息已成功放入消息隊列,則返回true。失敗時返回false,而失敗的原因通常是因為處理消息隊列正在退出。代碼分析到這里可以得出以下兩點結(jié)論了
Handler在sendMessage時會將自己設(shè)置給Message的target變量即將自己與發(fā)送的消息綁定。Handler的sendMessage是將Message放入MessageQueue中。到了這里已經(jīng)知道Handler的sendMessage是將消息放進(jìn)MessageQueue中,那么又是怎樣從MessageQueue中拿到消息的呢?想要知道答案請繼續(xù)閱讀。
怎樣從MessageQueue中獲取Message??在文章的前面,貼出了ActivityThread類中的main方法的代碼,不知道細(xì)心的你有沒有注意到,在main方法的結(jié)尾處調(diào)用了一句代碼
Looper.loop();1好了,現(xiàn)在可以看看*Looper.loop();*這句代碼到底做了什么了loop方法中的代碼如下
/**? ? ?* Run the message queue in this thread. Be sure to call? ? ?* {@link #quit()} to end the loop.? ? ?*/? ? public static void loop() {? ? ? ? final Looper me = myLooper();//通過myLooper方法拿到與主線程綁定的Looper? ? ? ? if (me == null) {? ? ? ? ? ? throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");? ? ? ? }? ? ? ? final MessageQueue queue = me.mQueue;//從Looper中得到MessageQueue
? ? ? ? // Make sure the identity of this thread is that of the local process,? ? ? ? // and keep track of what that identity token actually is.? ? ? ? Binder.clearCallingIdentity();? ? ? ? final long ident = Binder.clearCallingIdentity();
? ? ? ? //開始死循環(huán)? ? ? ? for (;;) {? ? ? ? ? ? //從消息隊列中不斷取出消息? ? ? ? ? ? Message msg = queue.next(); // might block? ? ? ? ? ? if (msg == null) {? ? ? ? ? ? ? ? // No message indicates that the message queue is quitting.? ? ? ? ? ? ? ? return;? ? ? ? ? ? }
? ? ? ? ? ? // This must be in a local variable, in case a UI event sets the logger? ? ? ? ? ? final Printer logging = me.mLogging;? ? ? ? ? ? if (logging != null) {? ? ? ? ? ? ? ? logging.println(">>>>> Dispatching to " + msg.target + " " +? ? ? ? ? ? ? ? ? ? ? ? msg.callback + ": " + msg.what);? ? ? ? ? ? }
? ? ? ? ? ? final long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
? ? ? ? ? ? final long traceTag = me.mTraceTag;? ? ? ? ? ? if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {? ? ? ? ? ? ? ? Trace.traceBegin(traceTag, msg.target.getTraceName(msg));? ? ? ? ? ? }? ? ? ? ? ? final long start = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();? ? ? ? ? ? final long end;? ? ? ? ? ? try {? ? ? ? ? ? ? ? //這句代碼是重點? ? ? ? ? ? ? ? msg.target.dispatchMessage(msg);? ? ? ? ? ? ? ? end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();? ? ? ? ? ? } finally {? ? ? ? ? ? ? ? if (traceTag != 0) {? ? ? ? ? ? ? ? ? ? Trace.traceEnd(traceTag);? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ? if (slowDispatchThresholdMs > 0) {? ? ? ? ? ? ? ? final long time = end - start;? ? ? ? ? ? ? ? if (time > slowDispatchThresholdMs) {? ? ? ? ? ? ? ? ? ? Slog.w(TAG, "Dispatch took " + time + "ms on "? ? ? ? ? ? ? ? ? ? ? ? ? ? + Thread.currentThread().getName() + ", h=" +? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.target + " cb=" + msg.callback + " msg=" + msg.what);? ? ? ? ? ? ? ? }? ? ? ? ? ? }
? ? ? ? ? ? if (logging != null) {? ? ? ? ? ? ? ? logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);? ? ? ? ? ? }
? ? ? ? ? ? // Make sure that during the course of dispatching the? ? ? ? ? ? // identity of the thread wasn't corrupted.? ? ? ? ? ? final long newIdent = Binder.clearCallingIdentity();? ? ? ? ? ? if (ident != newIdent) {? ? ? ? ? ? ? ? Log.wtf(TAG, "Thread identity changed from 0x"? ? ? ? ? ? ? ? ? ? ? ? + Long.toHexString(ident) + " to 0x"? ? ? ? ? ? ? ? ? ? ? ? + Long.toHexString(newIdent) + " while dispatching to "? ? ? ? ? ? ? ? ? ? ? ? + msg.target.getClass().getName() + " "? ? ? ? ? ? ? ? ? ? ? ? + msg.callback + " what=" + msg.what);? ? ? ? ? ? }
? ? ? ? ? ? msg.recycleUnchecked();? ? ? ? }? ? }12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576上面的代碼,我已經(jīng)進(jìn)行了部分注釋,這里有一句代碼非常重要
?msg.target.dispatchMessage(msg);1執(zhí)行到這句代碼,說明已經(jīng)從消息隊列中拿到了消息,還記得msg.target嗎?就是Message中的target變量呀!也就是發(fā)送消息的那個Handler,所以這句代碼的本質(zhì)就是調(diào)用了Handler中的dispatchMessage(msg)方法,代碼分析到這里是不是有點小激動了呢!穩(wěn)住!下面看下dispatchMessage(msg)這個方法,代碼如下
/**? ? ?* Handle system messages here.? ? ?*/? ? public void dispatchMessage(Message msg) {? ? ? ? if (msg.callback != null) {? ? ? ? ? ? handleCallback(msg);? ? ? ? } else {? ? ? ? ? ? if (mCallback != null) {? ? ? ? ? ? ? ? if (mCallback.handleMessage(msg)) {? ? ? ? ? ? ? ? ? ? return;? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? ? ? ? ? handleMessage(msg);? ? ? ? }? ? }123456789101112131415現(xiàn)在來一句句的來分析上面的代碼,先看下這句
if (msg.callback != null) {? ? ? ? ? ? handleCallback(msg);? ? ? ? }?123msg.callback就是Runnable對象,當(dāng)msg.callback不為null時會調(diào)用 handleCallback(msg)方法,先來看下 handleCallback(msg)方法,代碼如下
?private static void handleCallback(Message message) {? ? ? ? message.callback.run();? ? }123上面的代碼就是調(diào)用了Runnable的run方法。那什么情況下**if (msg.callback != null)**這個條件成立呢!還記得使用Handler的另一種方法嗎?就是調(diào)用Handler的post方法呀!這里說明一下,使用Handler其實是有兩種方法的
使用Handler的sendMessage方法,最后在handleMessage(Message msg)方法中來處理消息。使用Handler的post方法,最后在Runnable的run方法中來處理,代碼如下public class MainActivity extends AppCompatActivity implements View.OnClickListener {? ? private Button mTimeCycle,mStopCycle;? ? private Runnable mRunnable;
? ? @Override? ? protected void onCreate(Bundle savedInstanceState) {? ? ? ? super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_main);? ? ? ? initView();? ? }
? ? private void initView() {? ? ? ? mTimeCycle = findViewById(R.id.btn_time_cycle);? ? ? ? mTimeCycle.setOnClickListener(this);? ? ? ? mStopCycle = findViewById(R.id.btn_stop_cycle);? ? ? ? mStopCycle.setOnClickListener(this);

? ? ? ? mRunnable = new Runnable() {? ? ? ? ? ? @Override? ? ? ? ? ? public void run() {? ? ? ? ? ? ? ? Toast.makeText(MainActivity.this, "正在循環(huán)!!!", Toast.LENGTH_SHORT).show();? ? ? ? ? ? ? ? mHandler.postDelayed(mRunnable, 1000);? ? ? ? ? ? }? ? ? ? };? ? }
? ? @Override? ? public void onClick(View v) {? ? ? ? switch (v.getId()) {? ? ? ? ? ? case R.id.btn_time_cycle:? ? ? ? ? ? ? ? mHandler.post(mRunnable);? ? ? ? ? ? ? ? break;? ? ? ? ? ? case R.id.btn_stop_cycle:? ? ? ? ? ? ? ? mHandler.removeCallbacks(mRunnable);? ? ? ? ? ? ? ? break;? ? ? ? }? ? }}123456789101112131415161718192021222324252627282930313233343536373839第一種方法,我們已經(jīng)分析了,下面來分析一下第二種使用方式的原理,先看下Handler的post的方法做了什么,代碼如下
/**? ? ?* Causes the Runnable r to be added to the message queue.? ? ?* The runnable will be run on the thread to which this handler is?? ? ?* attached.?? ? ?*??? ? ?* @param r The Runnable that will be executed.? ? ?*?? ? ?* @return Returns true if the Runnable was successfully placed in to the?? ? ?*? ? ? ? ?message queue.? Returns false on failure, usually because the? ? ?*? ? ? ? ?looper processing the message queue is exiting.? ? ?*/? ? public final boolean post(Runnable r)? ? {? ? ? ?return? sendMessageDelayed(getPostMessage(r), 0);? ? }
?private static Message getPostMessage(Runnable r) {? ? ? ? Message m = Message.obtain();? ? ? ? m.callback = r;? ? ? ? return m;? ? }123456789101112131415161718192021由上面的代碼不難看出,post方法最終也是將Runnable封裝成消息,然后將消息放進(jìn)MessageQueue中。下面繼續(xù)分析dispatchMessage方法中的代碼
else {? ? //if中的代碼其實是和if (msg.callback != null) {handleCallback(msg);}?? ? //原理差不多的,只不過mCallback是Handler中的成員變量。? ? ? ? ? ? if (mCallback != null) {? ? ? ? ? ? ? ? if (mCallback.handleMessage(msg)) {? ? ? ? ? ? ? ? ? ? return;? ? ? ? ? ? ? ? }? ? ? ? ? ? }? ? //當(dāng)上面的條件都不成立時,就會調(diào)用這句代碼? ? ? ? ? ? handleMessage(msg);? ? ? ? }1234567891011上面的代碼就不分析了,我已經(jīng)在代碼中進(jìn)行了注釋,下面再看下**handleMessage(msg)**這個方法,代碼如下
/**? ? ?* Subclasses must implement this to receive messages.? ? ?*/? ? public void handleMessage(Message msg) {? ? }12345其實,他就是一個空方法,具體的代碼讓我們自己重寫這個方法進(jìn)行處理。代碼分析到這里,已經(jīng)可以給出下面問題的答案了。
Handler明明是在子線程中發(fā)的消息怎么會跑到主線程中了呢?Handler的發(fā)送消息handleMessage又是怎么接收到的呢?在子線程中Handler在發(fā)送消息的時候已經(jīng)把自己與當(dāng)前的message進(jìn)行了綁定,在通過Looper.loop()開啟輪詢message的時候,當(dāng)獲得message的時候會調(diào)用 與之綁定的Handler的**handleMessage(Message msg)**方法,由于Handler是在主線程創(chuàng)建的,所以自然就由子線程切換到了主線程。
總結(jié)??上面已經(jīng)嗯將Handler的源碼分析了一遍,現(xiàn)在來進(jìn)行一些總結(jié):
1、Handler的工作原理??在使用Handler之前必須要調(diào)用Looper.prepare()這句代碼,這句代碼的作用是將Looper與當(dāng)前的線程進(jìn)行綁定,在實例化Handler的時候,通過Looper.myLooper()獲取Looper,然后再獲得Looper中的MessageQueue。在子線程中調(diào)用Handler的sendMessage方法就是將Message放入MessageQueue中,然后調(diào)用Looper.loop()方法來從MessageQueue中取出Message,在取到Message的時候,執(zhí)行 **msg.target.dispatchMessage(msg);**這句代碼,這句代碼就是從當(dāng)前的Message中取出Handler然后執(zhí)行Handler的handleMessage方法。
2、Handler、Message、MessageQueue以及Looper之間的關(guān)系??在介紹它們之間的關(guān)系之前,先說一下它們各自的作用。
Handler:負(fù)責(zé)發(fā)送和處理消息。Message:用來攜帶需要的數(shù)據(jù)。MessageQueue:消息隊列,隊列里面的內(nèi)容就是Message。Looper:消息輪巡器,負(fù)責(zé)不停的從MessageQueue中取Message。它們的關(guān)系如下圖(圖片來源于網(wǎng)上)


3、在子線程中使用Handler??在子線程中使用Handler的方式如下
class LooperThread extends Thread {? ? public Handler mHandler;? ? public void run() {? ? ? ? Looper.prepare();? ? ? ? mHandler = new Handler() {? ? ? ? ? ? public void handleMessage(Message msg) {? ? ? ? ? ? ? ? // process incoming messages here? ? ? ? ? ? }? ? ? ? };? ? ? ? Looper.loop();? ? }}123456789101112上面的代碼來自官方的源碼。
結(jié)束語??本文將Handler的機(jī)制詳細(xì)講解了一遍,包括在面試中有關(guān)Handler的一些問題,在文章中也能找到答案。順便說下閱讀代碼應(yīng)該注意的地方,在分析源碼之前應(yīng)該知道你分析代碼的目的,就是你為了得到什么答案而分析代碼;在分析代碼時切記要避輕就重,不要想著要搞懂每句代碼做了什么,要找準(zhǔn)大方向。文中的代碼已上傳到GitHub,可以在這里獲取,與Handler有關(guān)的源碼在我上傳的源碼的handler包中。
ps: 歷史文章中有干貨哦!
轉(zhuǎn)載請注明出處:www.wizardev.cn---------------------?作者:wizardev?來源:CSDN?原文:https://blog.csdn.net/fnhfire_7030/article/details/79518819?版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!

轉(zhuǎn)載于:https://www.cnblogs.com/Jeely/p/10949274.html

總結(jié)

以上是生活随笔為你收集整理的Android:异步处理之Handler+Thread的应用(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

一区二区三区电影大全 | 99久在线精品99re8热视频 | 久久人91精品久久久久久不卡 | 992tv人人网tv亚洲精品 | 亚洲3级| 久草在线最新免费 | 久久久久免费精品国产小说色大师 | 丁香网婷婷| 日韩免费在线视频观看 | 欧美一区三区四区 | 国产伦精品一区二区三区无广告 | 国产精品第一页在线观看 | 天天·日日日干 | 免费在线色电影 | 国产裸体永久免费视频网站 | 亚洲春色综合另类校园电影 | 国产精品视频观看 | 日日综合 | 日韩系列在线 | 亚洲另类视频在线 | 色播99 | 久久久久伊人 | 五月天婷婷综合 | 久久久久欠精品国产毛片国产毛生 | 天天色欧美 | 欧美精品久久久久a | 亚洲码国产日韩欧美高潮在线播放 | 国产最顶级的黄色片在线免费观看 | 99久热在线精品 | 在线看中文字幕 | 久久婷婷一区 | 久久免费a| bbb搡bbb爽爽爽| 人人草在线观看 | 久久久久国产免费免费 | 在线看成人av | 伊人久久精品久久亚洲一区 | 亚洲国产精品一区二区尤物区 | 国产二区精品 | 69av在线播放 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | 日韩精品久久久久久久电影竹菊 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 日日夜夜免费精品视频 | 午夜影院在线观看18 | 91精品区| 日韩素人在线观看 | 高清av免费看 | 国产麻豆成人传媒免费观看 | 久久久免费视频播放 | 一区二区三区不卡在线 | 久久看看 | 激情五月婷婷网 | 婷婷开心久久网 | 免费看污黄网站 | 五月婷婷播播 | 久久深爱网 | 92精品国产成人观看免费 | 久久a热6| a资源在线 | 久久激情五月婷婷 | 91视频91蝌蚪 | 99国产在线观看 | 免费日韩一区二区三区 | 久久免费成人精品视频 | 国产不卡精品视频 | 亚洲人人网 | 欧美大片大全 | 国产一级二级在线播放 | 涩五月婷婷 | 久久国产成人午夜av影院宅 | 天天天天色射综合 | 亚洲精品国内 | 涩涩资源网 | 久二影院| 中文字幕一区二区三区乱码不卡 | 免费91在线观看 | 国产热re99久久6国产精品 | 久久av不卡 | 国产九色在线播放九色 | av亚洲产国偷v产偷v自拍小说 | 日韩在线视频一区二区三区 | 久久av网 | 91亚洲精品在线观看 | 欧美色婷婷| 亚洲国产精品久久久久久 | 久久久国产影视 | 97视频入口免费观看 | 国产精品va | 91日韩精品一区 | 国产亚洲精品久久久久久久久久久久 | 中文字幕乱偷在线 | 久久久精品网站 | 一级特黄aaa大片在线观看 | 日韩精品免费一区 | 色婷久久 | 国产精品成人a免费观看 | a黄色| 亚洲电影院| 欧美国产亚洲精品久久久8v | 综合网五月天 | 色资源网在线观看 | 久艹视频在线免费观看 | av免费黄色| 色噜噜狠狠狠狠色综合久不 | 欧美一级电影免费观看 | 91在线视频免费 | 亚洲网久久| 久久久午夜精品福利内容 | 99视频在线看 | 日韩av三区 | 国产在线免费观看 | 久久久影片 | 国产精品手机在线观看 | 波多野结衣在线视频免费观看 | 婷婷电影在线观看 | 国产精品久久久久久久久久妇女 | 国产中文字幕第一页 | 韩国一区二区三区在线观看 | 成人在线观看免费视频 | 国产成人精品一区一区一区 | 亚洲美女精品区人人人人 | 久久只精品99品免费久23小说 | 免费观看成人 | 日韩在线免费观看视频 | 婷婷网五月天 | 日韩欧美高清在线观看 | 久草在线免费看视频 | 久久久久国产免费免费 | 亚洲一区av | 亚洲精品在线视频观看 | 国产精品女人久久久 | 午夜18视频在线观看 | 亚洲精品一区二区精华 | 久久精品视频国产 | 欧美大荫蒂xxx | 伊人天堂网 | 久久久高清 | 综合久久五月天 | 久青草影院 | 2018好看的中文在线观看 | 国产在线毛片 | 国产精品国产三级国产 | 中文字幕成人一区 | 99超碰在线观看 | 日韩综合在线观看 | 日韩一区二区三区观看 | 欧美日韩首页 | 在线观看日本高清mv视频 | 日日色综合 | 亚洲劲爆av | 亚洲综合日韩在线 | 免费av片在线 | 日日夜夜av | 97超在线 | 中国老女人日b | 午夜电影久久久 | 日韩高清在线不卡 | www免费| 91亚洲精品乱码久久久久久蜜桃 | 成人a在线观看高清电影 | 国产xxxx| 黄色中文字幕在线 | 香蕉久草 | 探花视频免费观看高清视频 | 天天爱天天操天天射 | 亚洲成年片 | 99精品视频免费全部在线 | 欧美日韩高清一区二区 国产亚洲免费看 | 天天色婷婷 | 欧美亚洲另类在线视频 | 色是在线视频 | 2021国产精品 | 中文字幕乱码视频 | 国产一级黄色电影 | 黄色一级大片在线免费看国产一 | 国产黄色精品 | 97av影院| 欧美精品在线观看一区 | 日韩高清久久 | 久久久免费电影 | 国产香蕉97碰碰碰视频在线观看 | 人人爽人人爽人人片av | 中文字幕色播 | 91人人视频在线观看 | 久久精品亚洲综合专区 | 天天色天天射天天操 | 91人人射 | 日本性生活一级片 | 国产不卡在线播放 | 久草在线视频看看 | 狠狠干狠狠色 | 国产黄色在线观看 | 国产精久久 | 天天干夜夜操视频 | 国产婷婷色 | 日韩乱码中文字幕 | 亚洲综合激情网 | 四虎永久精品在线 | 丁香婷婷综合网 | 成人av在线一区二区 | 黄色a在线| 在线免费观看黄色 | 国产精品久久久久一区二区三区共 | 日韩精品一区二区三区在线视频 | 99久在线精品99re8热视频 | 免费色视频网站 | 久草精品在线观看 | 欧美性色黄大片在线观看 | 91网站观看 | 国产亚洲精品成人av久久ww | 久久久久久久av麻豆果冻 | 色综合国产 | .国产精品成人自产拍在线观看6 | 黄色视屏av | 日韩欧美在线一区二区 | 国产精品久一 | 中文在线字幕免费观看 | 99精品免费久久久久久日本 | 日本性视频 | 欧美激情综合五月色丁香小说 | 97超在线| 天天操天天操天天干 | 精品一区二三区 | 在线色资源 | 精品亚洲欧美无人区乱码 | 成人免费观看av | 久久久激情视频 | 丰满少妇对白在线偷拍 | 中文字幕在线观看91 | 人人看人人 | 成人在线电影观看 | 999ZYZ玖玖资源站永久 | 欧美一级视频在线观看 | 免费av网址大全 | 国产精品99精品久久免费 | 国产视频在线观看一区 | 99视频偷窥在线精品国自产拍 | 伊人激情网 | 91精品福利在线 | av免费看av| 免费看一级一片 | 欧美人体xx | 国产精品99久久免费黑人 | 国产精品大片免费观看 | 国产69精品久久久久久久久久 | 五月激情婷婷丁香 | 亚洲va韩国va欧美va精四季 | 极品美女被弄高潮视频网站 | 欧美韩日视频 | 日本中文字幕久久 | 午夜视频黄| 91精品秘密在线观看 | 一区二区三区久久精品 | 91在线日本 | 免费av视屏| 亚洲妇女av| 黄色大片日本免费大片 | 久久久久久免费毛片精品 | 久久99亚洲精品久久 | 亚洲精品国产成人 | 精品久久久久久久 | 黄色视屏av | 片网址| 2024国产在线| 成人免费观看网站 | 欧美日韩有码 | 国产一区二区视频在线 | 国产精品99久久久久久小说 | 日本护士三级少妇三级999 | 99久久久久久久久 | 国产在线久草 | 亚洲伊人av | 最近中文字幕免费 | 久久亚洲在线 | 热久在线| 成人动态视频 | 久久久免费电影 | 三级动态视频在线观看 | 91亚洲精品乱码久久久久久蜜桃 | 国产精品成人一区二区三区吃奶 | 久久成人一区二区 | 色搞搞 | 日韩电影在线观看一区二区 | 碰超人人| 国产高清精品在线 | 美女视频黄频大全免费 | 偷拍区另类综合在线 | 91人人干 | 国产在线免费av | 欧美精品在线免费 | 激情深爱.com | 精品一区二区久久久久久久网站 | 这里只有精品视频在线 | 香蕉97视频观看在线观看 | 在线 成人 | 久久免费电影网 | 一级欧美一级日韩 | 一区二区三区免费播放 | 日韩av不卡在线播放 | 国产午夜精品一区二区三区嫩草 | 丝袜护士aⅴ在线白丝护士 天天综合精品 | 久久电影日韩 | av在线h| 97福利 | 国产精品免费在线 | 日韩精品视频在线免费观看 | 黄色的网站免费看 | 国产成人a亚洲精品v | 欧美日韩在线观看不卡 | 欧美在线1区 | 一二区精品 | 人人艹人人 | 丰满少妇高潮在线观看 | 精品国产一区二区三区不卡 | 97福利社 | 日韩在线国产精品 | 国产精品免费久久久久久 | 久久久久久久久久国产精品 | 91在线播放综合 | 色99中文字幕| 色综合色综合久久综合频道88 | 一区在线电影 | 嫩模bbw搡bbbb搡bbbb | 国产精品黄 | 久久精品国产99国产 | 美女网站在线看 | 欧美激情精品久久久久久变态 | 精品亚洲va在线va天堂资源站 | 日本巨乳在线 | 久久精品波多野结衣 | 久久99热精品这里久久精品 | 中文字幕中文字幕中文字幕 | 天天草夜夜 | 亚洲欧洲一级 | 成人国产在线 | 久久99国产精品视频 | 日本三级不卡视频 | 成人久久精品 | 视频二区| 国产精品二区三区 | 亚洲精品中文在线 | 精品在线视频一区二区三区 | 国产高清不卡在线 | 日韩在线免费 | 色噜噜狠狠色综合中国 | 有码一区二区三区 | 四虎影视8848dvd | 日韩理论视频 | 一区二区观看 | 欧美日韩性 | 亚洲天堂网在线播放 | 美女久久久久久久久久久 | 九九九九热精品免费视频点播观看 | 欧美日本不卡视频 | 日韩一区二区三区观看 | 99爱视频在线观看 | 波多野结衣久久精品 | 国产成人精品在线播放 | 欧美日韩一区二区在线 | 欧美综合在线视频 | 69成人在线| 婷婷在线色 | 波多野结衣精品 | 色综合亚洲精品激情狠狠 | 欧美国产日韩在线视频 | 婷婷国产一区二区三区 | 麻豆久久久久久久 | 91av在线免费| 日韩免费看片 | 精品色999 | 国产高清久久 | 黄色一区二区在线观看 | 99国产精品久久久久久久久久 | av成人在线播放 | aaa毛片视频 | 国产精久久久久久妇女av | www.国产高清 | 亚洲精品一区二区久 | 欧美另类成人 | 国产精品夜夜夜一区二区三区尤 | 色婷婷激情 | 九九热在线精品视频 | 美女网站色 | www免费看片com | 国产999精品久久久久久麻豆 | 亚洲视频六区 | 黄色免费网站大全 | 亚洲v精品 | 日韩精品一区电影 | 日韩综合精品 | 成人中文字幕av | www.久久com| 99在线免费观看视频 | 免费黄色a网站 | 激情xxxx| 婷婷久久一区二区三区 | 操操色| 婷婷综合激情 | 欧美,日韩 | 国产a精品| 日韩在线观看的 | 91成人免费在线 | 一区二区高清在线 | 天天干天天拍天天操 | 久久久久久久久久影视 | 一区二区国产精品 | 香蕉影院在线观看 | 国产一级片播放 | 日韩3区| 久久久久免费精品国产小说色大师 | 日本中文字幕网站 | 色婷婷综合激情 | 美女精品久久久 | 久久久久久久久久久电影 | 国产亚洲精品久 | 视频在线91 | 久久精品国产成人精品 | 国产成人黄色在线 | 天天干天天天 | 97香蕉超级碰碰久久免费软件 | 国产美女精品在线 | 亚洲欧美在线综合 | 亚洲精品视频免费看 | 九九热中文字幕 | 亚洲性xxxx | 激情欧美网 | 久草香蕉在线 | 国产日韩在线一区 | 999毛片| 91秒拍国产福利一区 | 欧美一区二区三区在线看 | 亚欧洲精品视频在线观看 | 久久一区二区三区日韩 | 蜜臀av夜夜澡人人爽人人 | 色婷婷视频在线 | 97视频免费在线 | 黄色a在线观看 | 成人在线视频论坛 | 日韩欧美视频免费观看 | 黄色片网站免费 | 91麻豆高清视频 | 日韩精品播放 | 亚洲a资源 | 激情五月五月婷婷 | 精品国产中文字幕 | 婷婷丁香国产 | 亚洲男男gaygayxxxgv | 国产精品午夜免费福利视频 | 久久久久久久久久久影院 | 91精品国产自产老师啪 | 日韩va亚洲va欧美va久久 | 天天摸天天操天天舔 | 国产无套精品久久久久久 | 99久久婷婷国产 | 国内精品久久久久影院日本资源 | 欧美 日韩 成人 | 91成人破解版 | 日韩高清在线不卡 | 91精品小视频 | 免费a v在线 | 超碰电影在线观看 | 99久久99久国产黄毛片 | 永久免费的啪啪网站免费观看浪潮 | 中文字幕在线播放第一页 | 亚洲成aⅴ人片久久青草影院 | 伊人成人激情 | 中文字幕在线播放日韩 | www.黄色小说.com| 天天搞天天干 | 在线免费观看黄色大片 | 九九在线精品视频 | 亚洲成人中文在线 | 国产又粗又猛又色又黄网站 | 国产精品一区二区久久 | 国模视频一区二区三区 | 超级碰碰碰免费视频 | 亚洲永久精品在线观看 | 亚洲成av人片一区二区梦乃 | 日本免费一二三区 | 一区精品在线 | 麻豆一二| 亚洲黄色高清 | 国产欧美三级 | 99精品视频免费观看视频 | 久久一区二区免费视频 | 婷婷激情五月综合 | 精品理论片 | 免费a视频在线观看 | 国产免费嫩草影院 | 国产又粗又猛又色又黄视频 | 日韩久久久久久久久久久久 | 欧美日本啪啪无遮挡网站 | 91精品国产91久久久久福利 | 麻豆国产在线视频 | av官网在线 | 日本中文字幕网站 | 久久精品电影网 | 丝袜美腿亚洲 | 婷婷综合影院 | 天天干夜夜想 | 天天插天天干天天操 | 97精品国产91久久久久久久 | 亚洲精品福利在线 | 国产一区免费观看 | 特黄特黄的视频 | 久久久久久久国产精品视频 | 免费观看mv大片高清 | 超碰个人在线 | 操操操人人人 | 精品在线观看国产 | 黄色一级免费 | 91毛片在线| 国产精品密入口果冻 | 国产一区二区手机在线观看 | 日韩高清在线一区 | 香蕉视频网址 | 一区二区视频在线播放 | 久久草精品 | 免费视频a| 美女av电影 | 欧美日韩在线视频一区 | 黄污视频网站 | 成人99免费视频 | 久久久久久久影视 | 狠狠操狠狠干天天操 | 婷婷丁香激情网 | 99热这里只有精品久久 | 日韩免费大片 | 亚洲精品无 | 中文字幕第一页在线播放 | 五月天亚洲综合 | 成人黄色在线电影 | 在线免费观看黄色小说 | 超碰在线观看av.com | 国产精品激情偷乱一区二区∴ | 日本精品视频在线播放 | 在线一二三四区 | 成人免费视频免费观看 | 国产一线二线三线性视频 | 欧美a级一区二区 | 中文字幕欧美三区 | 中文字幕精品三区 | 97人人精品 | 亚洲精品福利在线观看 | 日本精品久久久久中文字幕5 | 色婷婷影视| 久久久国产精品久久久 | 日韩成人中文字幕 | av三级在线看 | 黄色最新网址 | 激情综合色综合久久综合 | 五月婷婷电影网 | 日韩中文字幕免费 | 国产精品专区h在线观看 | 欧美污在线观看 | 久草在线免费新视频 | 91免费观看视频在线 | 国产又粗又猛又色又黄视频 | 国产福利专区 | 久久激情小说 | h视频在线看| 久久成人精品视频 | 日韩欧美69 | 在线观看久久 | 久久久久欠精品国产毛片国产毛生 | 开心丁香婷婷深爱五月 | 五月婷香蕉久色在线看 | 久久国产区 | 色婷婷综合久久久久中文字幕1 | 国产成人精品福利 | 九九av | 狠狠色丁香久久婷婷综合五月 | 日韩av福利在线 | 五月综合激情婷婷 | 国产精品破处视频 | 玖玖国产精品视频 | 国产韩国精品一区二区三区 | 国产精品久久久久久一区二区 | 欧美少妇bbwhd | 亚洲精品1234区 | 国产成人久久久久 | 久久久久久久久久久久久久免费看 | 国产一区在线精品 | 一级精品视频在线观看宜春院 | 国产亚洲小视频 | 狠狠干成人综合网 | 正在播放国产精品 | 91理论片午午伦夜理片久久 | 激情电影在线观看 | 国产成人精品久久久久蜜臀 | 九九九热 | 人人爽久久久噜噜噜电影 | 一区二区欧美在线观看 | 97超碰福利久久精品 | 国产香蕉视频在线观看 | 欧美一二三区播放 | 婷婷中文字幕综合 | 国内精品中文字幕 | 日韩免费一区二区三区 | 国产精品人成电影在线观看 | 国产精品国产三级国产aⅴ无密码 | 在线视频app | 久久综合狠狠综合 | 免费观看日韩av | 色黄www小说 | 最近中文字幕在线中文高清版 | 亚洲免费视频在线观看 | 在线亚洲成人 | 成人毛片一区二区三区 | 在线综合 亚洲 欧美在线视频 | 亚洲特级片 | 夜夜操网站 | 午夜av免费在线观看 | 国产又粗又猛又黄又爽的视频 | 亚州精品天堂中文字幕 | av免费线看| 国产精品theporn | 青青草国产在线 | 国产不卡免费视频 | 精品福利国产 | 国产麻豆精品免费视频 | 91九色蝌蚪视频在线 | 99色免费视频 | av夜夜操 | 天天操天天添 | 亚洲成色| 500部大龄熟乱视频使用方法 | 91av在线电影| 亚洲在线成人精品 | 在线免费色 | 精品国产一区二区三区久久影院 | 97在线观| 国产精品视频大全 | 日韩精品一区二区在线 | 又紧又大又爽精品一区二区 | 欧美-第1页-屁屁影院 | 久久久成人精品 | 亚洲精品中文字幕在线观看 | 中文字幕亚洲欧美日韩2019 | 婷婷四房综合激情五月 | 精品视频国产一区 | 亚洲黄色免费在线看 | 成年人天堂com | 久久在线观看视频 | 丁香花在线视频观看免费 | 亚洲专区 国产精品 | 热久久99这里有精品 | 国产高清精品在线 | 亚洲精品女人 | 国产精品毛片一区二区 | 国产精品女主播一区二区三区 | 成人精品一区二区三区中文字幕 | 日韩精品中字 | 中文字幕在线观看完整版 | 99精品免费 | 亚洲一区二区观看 | 亚洲免费精品视频 | 日韩理论在线观看 | 日本中文字幕观看 | 在线有码中文字幕 | 夜夜夜草| 国产黄色片免费在线观看 | 麻豆国产在线播放 | 日本一区二区三区视频在线播放 | 玖玖玖国产精品 | 一区二区三区四区免费视频 | 国产成人av电影 | 天堂麻豆 | 一级做a爱片性色毛片www | av电影不卡在线 | 四虎精品成人免费网站 | 欧美激情xxxx | 99re8这里有精品热视频免费 | 久久精品99久久久久久 | 中文在线天堂资源 | 97超碰在线久草超碰在线观看 | 亚洲国内精品在线 | 操一草 | 久草在线免费资源站 | 午夜av免费看| 国产盗摄精品一区二区 | 日韩电影在线视频 | 97综合视频 | 在线国产99| 国产高清久久久久 | 97国产电影| 久99久在线 | 99在线观看视频 | 欧美国产高清 | 在线电影 你懂得 | 深夜免费福利 | 99r在线观看| 色婷婷在线观看视频 | 久久久精品网 | 在线免费av播放 | 嫩草av影院| 日韩免费在线观看视频 | 亚洲一区 影院 | 天天干 夜夜操 | 国产黄色免费电影 | 国内成人精品2018免费看 | av性网站| 亚洲国产三级 | 在线观看精品一区 | 91在线视频免费播放 | 久久精品国产精品亚洲精品 | 国产在线国偷精品产拍 | 国产精品美女久久久久aⅴ 干干夜夜 | 精品在线观 | 日一日干一干 | 亚洲免费视频观看 | 91在线视频网址 | a黄色影院| 欧洲一区精品 | 蜜臀av夜夜澡人人爽人人桃色 | 五月婷婷六月丁香在线观看 | 91精品区| 深夜激情影院 | 亚洲www天堂com| 日韩视频一区二区在线观看 | 日韩天堂网| 成人av免费在线观看 | 久久久天堂 | 天天射综合网站 | 一本色道久久综合亚洲二区三区 | 日韩精品视频在线观看免费 | 97在线免费观看视频 | a国产精品 | 久久久久亚洲精品 | 97福利在线 | 日韩av一区在线观看 | 久久电影中文字幕视频 | 久久69av| 99国产视频| 日韩黄色一级电影 | 超碰97中文 | 国产在线色 | 在线观看免费一区 | 婷婷六月天丁香 | 国产午夜精品一区二区三区欧美 | 天天操网 | 国模视频一区二区 | 2018好看的中文在线观看 | 久草99| 伊人色综合久久天天网 | 黄色大片入口 | 国内综合精品午夜久久资源 | 国产伦理一区二区 | 日韩欧美一区二区三区视频 | 黄色毛片视频免费观看中文 | 国精产品999国精产 久久久久 | 黄色免费高清视频 | 国产精彩视频一区二区 | 成人国产精品久久久久久亚洲 | 91九色在线观看 | 97在线视频网站 | 欧美精选一区二区三区 | 国产最顶级的黄色片在线免费观看 | 超碰国产人人 | 黄色大片免费网站 | av丝袜天堂 | 在线免费观看羞羞视频 | 午夜av在线 | 成人三级av | 国产中文字幕视频在线观看 | 成人午夜性影院 | 久久国产精品久久精品国产演员表 | 99久久99久久精品 | 成人免费视频在线观看 | 麻豆视频免费入口 | 99亚洲国产| 深爱激情久久 | 亚洲天堂精品视频 | 日韩高清黄色 | 一本一本久久aa综合精品 | 91入口在线观看 | 久章操| 亚洲精品美女久久久久 | 国产美女被啪进深处喷白浆视频 | 中文在线天堂资源 | 国产精品久久久久久吹潮天美传媒 | 亚洲婷婷综合色高清在线 | 久操视频在线免费看 | 91天天操 | 九九视频免费观看视频精品 | 在线色网站 | 国产精品手机在线播放 | 亚洲免费资源 | 免费观看黄 | 操操综合网 | 激情网色 | 久草国产在线观看 | 视频福利在线观看 | 欧美激情视频免费看 | www.99在线观看 | 一级片视频在线 | 久久久午夜剧场 | 成人精品视频 | 福利视频导航网址 | 一本—道久久a久久精品蜜桃 | 一区二区三区免费 | 成x99人av在线www | 久久精品伊人 | 国产 av 日韩| 香蕉久久国产 | 黄网站免费看 | 91精品在线播放 | 在线观看国产 | 天天鲁天天干天天射 | 精品国产一区二区三区久久久 | 久久大片网站 | 91精品福利在线 | 91 在线视频 | a级片在线播放 | 国内精品久久久久影院一蜜桃 | 国产精品亚洲人在线观看 | 欧美一级电影 | 午夜视频导航 | 久久久高清一区二区三区 | 香蕉视频啪啪 | 久久九九国产精品 | 日韩城人在线 | 久久久综合电影 | 国产做爰视频 | 国产99自拍| 一区二区三区在线免费观看 | 精品久久久久久久久中文字幕 | av综合站 | 91资源在线视频 | 九九导航 | 亚洲男男gⅴgay双龙 | 91免费观看视频在线 | 国产视频一区二区在线播放 | 99亚洲精品 | 日韩影视在线 | 国内外成人免费在线视频 | 亚洲视频免费 | 久久久久女人精品毛片 | 一区二区三区在线免费 | av天天澡天天爽天天av | 日韩免费电影在线观看 | 久久久久久久久久电影 | 国产97视频在线 | 国产手机精品视频 | 不卡精品 | av免费电影在线 | 精品女同一区二区三区在线观看 | 中文字幕 二区 | 91最新视频在线观看 | www.日本色 | 黄网站色| 婷婷久草| av黄色一级片 | 国产精品私人影院 | 中文字幕在线网址 | 日本中文字幕视频 | 91激情视频在线观看 | 久久久久久高清 | 99热最新网址 | 亚洲精品字幕在线 | 成年人免费观看国产 | 久久躁日日躁aaaaxxxx | 成年人视频在线免费 | 国产精品高清在线 | 99亚洲国产 | 精品久久久成人 | 亚洲精品在线免费观看视频 | 国产精品久久久久久吹潮天美传媒 | 91精品国自产拍天天拍 | 午夜久久久久久久久久久 | av高清免费在线 | 一区在线免费观看 | 日韩激情在线 | 国产成人一区二区三区电影 | 成人av日韩 | 色综合久久久久综合体 | 亚洲精品a区 | 久久男人免费视频 | 成人av资源网站 | 日韩精品一区二区免费视频 | 美女免费视频一区 | 91免费在线看片 | 成人免费看片98欧美 | 国产精品a成v人在线播放 | 一本—道久久a久久精品蜜桃 | 日本精品二区 | www.久久免费视频 | 国产精品一区二区美女视频免费看 | 国产精品com | 成人免费视频免费观看 | 天天操夜夜叫 | 一区在线观看视频 | 国内精品美女在线观看 | 视频1区2区 | 久久99精品久久久久久三级 | 91麻豆精品国产91久久久久 | 亚洲精品av在线 | av电影在线免费 | 一区二区三区免费播放 | 超级碰视频| 国产久草在线观看 | 久久成人精品视频 | 久久精品一区二区国产 | 国产91在线播放 | 婷婷亚洲五月 | 亚洲精品国 | 亚洲影视九九影院在线观看 | 91亚洲精品在线观看 | 青青草视频精品 | 日日草天天草 | 久久久久国产成人精品亚洲午夜 | 欧美成人视 | 91在线国内视频 | 国产成人av电影在线观看 | 久久国产精品视频免费看 | 成 人 黄 色视频免费播放 | 国产丝袜| 国产护士av | 视频在线观看亚洲 | 国产精品2020 | 在线欧美中文字幕 | 在线视频精品 | 米奇影视7777| www色,com| 国产视频不卡 | 亚洲精品黄色片 | 欧洲性视频 | 久久久免费 | 天天干,天天干 | 中文字幕在线观看第三页 | 91精品第一页 | 国产美女精品视频免费观看 | 在线免费视频 你懂得 | 精品久久1 | 极品美女被弄高潮视频网站 | 日本免费一二三区 | 去看片| 久久99精品久久久久婷婷 | 99视频精品| 91传媒91久久久 | 一区 二区电影免费在线观看 | 在线观看视频精品 | 成人a视频 | 成人午夜精品久久久久久久3d | 97超碰人人澡人人 | 激情五月伊人 | 国产韩国日本高清视频 | 国产精品麻豆欧美日韩ww | 狠狠色伊人亚洲综合网站野外 | 四虎免费在线观看视频 | 婷婷激情av | 天天色天天草天天射 | 国产精品视频全国免费观看 | 狠狠成人| 国产精久久久 | 亚洲精品午夜一区人人爽 | 亚洲综合导航 | 91亚洲影院| 91精品久久久久久久久久入口 | 女人高潮特级毛片 | 免费av观看网站 | 干av在线 | 亚洲成人软件 | av色一区 | 久在线观看视频 | 麻豆传媒视频在线免费观看 | 久久国产精品久久国产精品 | 国产高清绿奴videos | 国产精品激情在线观看 | 成人黄色av网站 | 丁香婷婷在线观看 | 色噜噜日韩精品欧美一区二区 | 五月婷影院 | aaa日本高清在线播放免费观看 | 精品国产美女在线 | 黄色一及电影 | 亚洲欧美日韩中文在线 | 大型av综合网站 | 久久毛片高清国产 | 国产69精品久久app免费版 | 久久久国产日韩 | 99精品视频免费观看视频 | 成人高清在线 | 又大又硬又黄又爽视频在线观看 | 国产成人精品综合久久久 | 在线视频1卡二卡三卡 | 久久你懂的 | 婷婷黄色片 | 亚洲天堂网站视频 | av最新资源 | 色吊丝在线永久观看最新版本 | 91视频免费国产 | 天堂av在线中文在线 | 国产一级二级三级在线观看 | 国产高清精品在线 | 五月天久久久 | 国产二区视频在线观看 |