黄a在线观看-黄a在线-黄a大片-黄色片在线看-黄色毛片免费-黄色大片网站

您的位置:首頁技術文章
文章詳情頁

Android教你如何發現APP卡頓的實現

瀏覽:68日期:2022-09-21 18:26:29

最近部門打算優化下 APP 在低端機上的卡頓情況,既然想優化,就必須獲取卡頓情況,那么如何獲取卡頓情況就是本文目的。

一般主線程過多的 UI 繪制、大量的 IO 操作或是大量的計算操作占用 CPU,導致 App 界面卡頓。只要我們能在發生卡頓的時候,捕捉到主線程的堆棧信息和系統的資源使用信息,即可準確分析卡頓發生在什么函數,資源占用情況如何。那么問題就是如何有效檢測 Android 主線程的卡頓發生?

用 adb 系統工具觀察 App 的卡頓數據情況,試圖重現場景來定位問題。

常用的方式是使用 adb SurfaceFlinger 服務和 adb gfxinfo 功能,在自動化操作 app 的過程中,使用 adb 獲取數據來監控 app 的流暢情況,發現出現出現卡頓的時間段,尋找出現卡頓的場景和操作。

方式1:adb shell dumpsysSurfaceFlinger

使用 ‘adb shell dumpsysSurfaceFlinger’ 命令即可獲取最近 127 幀的數據,通過定期執行 adb 命令,獲取幀數來計算出幀率 FPS。

方式2:adb shell dumpsys gfxinfo

使用 ‘adb shell dumpsys gfxinfo’ 命令即可獲取最新 128 幀的繪制信息,詳細包括每一幀繪制的 Draw,Process,Execute 三個過程的耗時,如果這三個時間總和超過 16.6ms 即認為是發生了卡頓。

已有的兩種方案比較適合衡量回歸卡頓問題的修復效果和判斷某些特定場景下是否有卡頓情況,然而,這樣的方式有幾個明顯的不足:

一般很難構造實際用戶卡頓的環境來重現; 這種方式操作起來比較麻煩,需編寫自動化用例,無法覆蓋大量的可疑場景,測試重現耗時耗人力; 無法衡量靜態頁面的卡頓情況; 出現卡頓的時候app無法及時獲取運行狀態和信息,開發定位困難。

隨著對Android 源碼的深入研究,也有了其他兩種比較方便的方式,并且這兩種方式侵入性小,占用內存低,能夠更好的用在實際場景中:

利用UI線程的Looper打印的日志匹配; 使用Choreographer.FrameCallback

利用 UI 線程的 Looper 打印的日志匹配

Android 主線程更新 UI。如果界面1秒鐘刷新少于 60 次,即 FPS 小于 60,用戶就會產生卡頓感覺。簡單來說,Android 使用消息機制進行 UI 更新,UI 線程有個 Looper,在其 loop方法中會不斷取出 message,調用其綁定的 Handler 在 UI 線程執行。如果在 handler 的 dispatchMesaage 方法里有耗時操作,就會發生卡頓。

下面來看下 Looper.loop( ) 的源碼

public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException('No Looper; Looper.prepare() wasn’t called on this thread.'); } final MessageQueue queue = me.mQueue; // 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(); // Allow overriding a threshold with a system prop. e.g. // adb shell ’setprop log.looper.1000.main.slow 1 && stop && start’ final int thresholdOverride =SystemProperties.getInt('log.looper.' + Process.myUid() + '.' + Thread.currentThread().getName() + '.slow', 0); boolean slowDeliveryDetected = false; 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); } // Make sure the observer won’t change while processing a transaction. final Observer observer = sObserver; final long traceTag = me.mTraceTag; long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs; long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs; if (thresholdOverride > 0) {slowDispatchThresholdMs = thresholdOverride;slowDeliveryThresholdMs = thresholdOverride; } final boolean logSlowDelivery = (slowDeliveryThresholdMs > 0) && (msg.when > 0); final boolean logSlowDispatch = (slowDispatchThresholdMs > 0); final boolean needStartTime = logSlowDelivery || logSlowDispatch; final boolean needEndTime = logSlowDispatch; if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0; final long dispatchEnd; Object token = null; if (observer != null) {token = observer.messageDispatchStarting(); } long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid); try {msg.target.dispatchMessage(msg);if (observer != null) { observer.messageDispatched(token, msg);}dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0; } catch (Exception exception) {if (observer != null) { observer.dispatchingThrewException(token, msg, exception);}throw exception; } finally {ThreadLocalWorkSource.restore(origWorkSource);if (traceTag != 0) { Trace.traceEnd(traceTag);} } if (logSlowDelivery) {if (slowDeliveryDetected) { if ((dispatchStart - msg.when) <= 10) { Slog.w(TAG, 'Drained'); slowDeliveryDetected = false; }} else { if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, 'delivery', msg)) { // Once we write a slow delivery log, suppress until the queue drains. slowDeliveryDetected = true; }} } if (logSlowDispatch) {showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, 'dispatch', msg); } 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(); } }

代碼中兩處標紅的地方,就是 msg.target.dispatchMessage(msg) 的執行前后索打印的 log。通過測量處理時間就能檢測到部分UI線程是否有耗時的操作。注意到這行執行代碼的前后,有兩個 logging.println 函數,如果設置了logging,會分別打印出 ”>>>>> Dispatching to “ 和 ”<<<<< Finished to “ 這樣的日志,這樣我們就可以通過兩次log的時間差值,來計算 dispatchMessage 的執行時間,從而設置閾值判斷是否發生了卡頓。

那么如何設置 logging 呢?

我們看下面的代碼:

/** * Control logging of messages as they are processed by this Looper. If * enabled, a log message will be written to <var>printer</var> * at the beginning and ending of each message dispatch, identifying the * target Handler and message contents. * * @param printer A Printer object that will receive log messages, or * null to disable message logging. */public final class Looper { private Printer mLogging; public void setMessageLogging(@Nullable Printer printer) { mLogging = printer; } } public interface Printer { void println(String x); }

Looper 的 mLogging 是私有的,并且提供了 setMessageLogging(@Nullable Printer printer) 方法,所以我們可以自己實現一個 Printer,在通過 setMessageLogging() 方法傳入即可,代碼如下:

public class BlockDetectByPrinter { public static void start() { Looper.getMainLooper().setMessageLogging(new Printer() { private static final String START = '>>>>> Dispatching'; private static final String END = '<<<<< Finished'; @Override public void println(String x) {if (x.startsWith(START)) { LogMonitor.getInstance().startMonitor();}if (x.startsWith(END)) { LogMonitor.getInstance().removeMonitor();} } }); }}

設置了logging后,loop方法會回調 logging.println 打印出每次消息執行的時間日志:”>>>>> Dispatching to “和”<<<<< Finished to “。BlockDetectByPrinter 的使用則在Application 的 onCreate 方法中調用 BlockDetectByPrinter.start() 即可。

我們可以簡單實現一個 LogMonitor 來記錄卡頓時候主線程的堆棧信息。當匹配到 >>>>> Dispatching 時,執行 startMonitor,會在 200ms(設定的卡頓閾值)后執行任務,這個任務負責在子線程(非UI線程)打印UI線程的堆棧信息。如果消息低于 200ms 內執行完成,就可以匹配到 <<<<< Finished 日志,那么在打印堆棧任務啟動前執行 removeMonitor 取消了這個任務,則認為沒有卡頓的發生;如果消息超過 200ms 才執行完畢,此時認為發生了卡頓,并打印 UI 線程的堆棧信息。

LogMonitor如何實現?

public class LogMonitor { private static final String TAG = 'LogMonitor'; private static LogMonitor sInstance = new LogMonitor(); private HandlerThread mLogThread = new HandlerThread('log'); private Handler mIoHandler; private static final long TIME_BLOCK = 200L; private LogMonitor() { mLogThread.start(); mIoHandler = new Handler(mLogThread.getLooper()); } private static Runnable mLogRunnable = new Runnable() { @Override public void run() { StringBuilder sb = new StringBuilder(); StackTraceElement[] stackTrace = Looper.getMainLooper().getThread().getStackTrace(); for (StackTraceElement s : stackTrace) {sb.append(s.toString() + 'n'); } Log.e(TAG, sb.toString()); } }; public static LogMonitor getInstance() { return sInstance; } public boolean isMonitor() { return mIoHandler.hasCallbacks(mLogRunnable); } public void startMonitor() { mIoHandler.postDelayed(mLogRunnable, TIME_BLOCK); } public void removeMonitor() { mIoHandler.removeCallbacks(mLogRunnable); }}

這里我們使用 HandlerThread 來構造一個 Handler,HandlerThread 繼承自 Thread,實際上就一個 Thread,只不過比普通的 Thread 多了一個 Looper,對外提供自己這個 Looper 對象的 getLooper 方法,然后創建 Handler 時將 HandlerThread 中的 looper 對象傳入。這樣我們的 mIoHandler 對象就是與 HandlerThread 這個非 UI 線程綁定的了,它處理耗時操作將不會阻塞UI。如果UI線程阻塞超過 200ms,就會在子線程中執行 mLogRunnable,打印出 UI 線程當前的堆棧信息,如果處理消息沒有超過 1000ms,則會實時的 remove 掉這個mLogRunnable 任務。

發生卡頓時打印出堆棧信息的大致內容如下,開發可以通過 log 定位耗時的地方。

2020-10-30 14:26:13.823 30359-30415/com.example.myproxyplugin E/LogMonitor: java.lang.Thread.sleep(Native Method) java.lang.Thread.sleep(Thread.java:443) java.lang.Thread.sleep(Thread.java:359) com.example.myproxyplugin.MainActivity$1.run(MainActivity.java:22) android.os.Handler.handleCallback(Handler.java:900) android.os.Handler.dispatchMessage(Handler.java:103) android.os.Looper.loop(Looper.java:219) android.app.ActivityThread.main(ActivityThread.java:8347) java.lang.reflect.Method.invoke(Native Method) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

優點:用戶使用 app 或者測試過程中都能從app層面來監控卡頓情況,一旦出現卡頓能記錄 app 狀態和信息, 只要dispatchMesaage執行耗時過大都會記錄下來,不再有前面兩種adb方式面臨的問題與不足。

缺點:需另開子線程獲取堆棧信息,會消耗少量系統資源。

在實際實現中,不同手機不同 Android 系統甚至是不同的 ROM 版本,Loop 函數不一定都能打印出 ”>>>>> Dispatching to “ 和 ”<<<<< Finished to “ 這樣的日志,導致該方式無法進行。

優化的策略:我們知道 Loop 函數開始和結束必會執行 println 打印日志,所以優化版本將卡頓的判斷改為,Loop輸出第一句 log 時當作 startMonitor,輸出下一句log時當作end時刻來解決這個問題。

其實 Looper 中有個 Observer 接口可以很好的完成這個任務,只是因為被標記為 hide 了,所以我們不能使用,不過可以知道下。

Observer 接口提供了三個方法,分別是監聽任務開始,結束,發生錯誤的回調。

/** {@hide} */ public interface Observer { /** * Called right before a message is dispatched. * * <p> The token type is not specified to allow the implementation to specify its own type. * * @return a token used for collecting telemetry when dispatching a single message. * The token token must be passed back exactly once to either * {@link Observer#messageDispatched} or {@link Observer#dispatchingThrewException} * and must not be reused again. * */ Object messageDispatchStarting(); /** * Called when a message was processed by a Handler. * * @param token Token obtained by previously calling * {@link Observer#messageDispatchStarting} on the same Observer instance. * @param msg The message that was dispatched. */ void messageDispatched(Object token, Message msg); /** * Called when an exception was thrown while processing a message. * * @param token Token obtained by previously calling * {@link Observer#messageDispatchStarting} on the same Observer instance. * @param msg The message that was dispatched and caused an exception. * @param exception The exception that was thrown. */ void dispatchingThrewException(Object token, Message msg, Exception exception); }

利用Choreographer.FrameCallback監控卡頓

Choreographer.FrameCallback 官方文檔鏈接(https://developer.android.com/reference/android/view/Choreographer.FrameCallback.html)

我們知道, Android 系統每隔 16ms 發出 VSYNC 信號,來通知界面進行重繪、渲染,每一次同步的周期為16.6ms,代表一幀的刷新頻率。SDK 中包含了一個相關類,以及相關回調。理論上來說兩次回調的時間周期應該在 16ms,如果超過了 16ms 我們則認為發生了卡頓,利用兩次回調間的時間周期來判斷是否發生卡頓(這個方案是 Android 4.1 API 16 以上才支持)。

這個方案的原理主要是通過 Choreographer 類設置它的 FrameCallback 函數,當每一幀被渲染時會觸發回調 FrameCallback, FrameCallback 回調 void doFrame (long frameTimeNanos) 函數。一次界面渲染會回調 doFrame 方法,如果兩次 doFrame 之間的間隔大于 16.6ms 說明發生了卡頓。

public class FPSFrameCallback implements Choreographer.FrameCallback { private static final String TAG = 'FPS_TEST'; private long mLastFrameTimeNanos = 0; private long mFrameIntervalNanos; public FPSFrameCallback(long lastFrameTimeNanos) { mLastFrameTimeNanos = lastFrameTimeNanos; // 1s 60 幀 mFrameIntervalNanos = (long) (1000000000 / 60.0); } @Override public void doFrame(long frameTimeNanos) { //初始化時間 if (mLastFrameTimeNanos == 0) { mLastFrameTimeNanos = frameTimeNanos; } final long jitterNanos = frameTimeNanos - mLastFrameTimeNanos; if (jitterNanos >= mFrameIntervalNanos) { final long skippedFrames = jitterNanos / mFrameIntervalNanos; if (skippedFrames > 30) {Log.i(TAG, 'Skipped ' + skippedFrames + ' frames! ' + 'The application may be doing too much work on its main thread.'); } } mLastFrameTimeNanos = frameTimeNanos; //注冊下一幀回調 Choreographer.getInstance().postFrameCallback(this); }}

本質和 log 沒太多區別,但是這個更加通用些,不會因為機型系統原因出現不可用的問題。

示例

下面進入實戰,看看代碼層面是如何實現的。

MainActivity 代碼如下:

public class MainActivity extends AppCompatActivity { Handler handler = new Handler(Looper.getMainLooper()); private final Runnable runnable = new Runnable() { @Override public void run() { try {Thread.sleep(600);handler.postDelayed(runnable, 500); } catch (InterruptedException e) {e.printStackTrace(); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Choreographer.getInstance().postFrameCallback(new FPSFrameCallback(System.nanoTime())); BlockDetectByPrinter.start(); } @Override protected void onResume() { super.onResume(); handler.postDelayed(runnable, 500); }}

收集到的堆棧信息如下:

2020-10-30 14:26:13.823 30359-30415/com.example.myproxyplugin E/LogMonitor: java.lang.Thread.sleep(Native Method) java.lang.Thread.sleep(Thread.java:443) java.lang.Thread.sleep(Thread.java:359) com.example.myproxyplugin.MainActivity$1.run(MainActivity.java:22) android.os.Handler.handleCallback(Handler.java:900) android.os.Handler.dispatchMessage(Handler.java:103) android.os.Looper.loop(Looper.java:219) android.app.ActivityThread.main(ActivityThread.java:8347) java.lang.reflect.Method.invoke(Native Method) com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

對于 FPS log 可以看到如下信息:

I/Choreographer: Skipped 64 frames! The application may be doing too much work on its main thread. I/FPS_TEST: Skipped 65 frames! The application may be doing too much work on its main thread.

如果你要把上面的方法用到自己的APP 中,那么還需要很多操作,具體可以閱讀參考文獻的內容。

參考文章

廣研Android卡頓監控系統

到此這篇關于Android教你如何發現APP卡頓的實現的文章就介紹到這了,更多相關Android APP卡頓內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Android
相關文章:
主站蜘蛛池模板: 欧洲黄视频| 久久99精品视频 | 少妇毛片| 色爱综合另类图片av | 男女裸体影院高潮 | 欧美久久久久久久 | 精品国产91亚洲一区二区三区www | 操mm影院| 91日韩欧美| 在线伊人 | 亚洲熟妇无码一区二区三区导航 | 久久精品人妻无码一区二区三区 | 亚洲毛片一区二区三区 | 在线播放国产精品 | 色综合久久久久综合一本到桃花网 | 一本久在线 | 国产一区二区精品免费 | 久久天天躁狠狠躁亚洲综合公司 | 欧美在线免费看 | 中文天堂资源在线 | 偷窥四川少妇野外啪啪 | 国产精品久久久久久久久久久久午衣片 | 久久久精品一区aaa片 | 中文字幕第2页不卡 | 777爽死你无码免费看一二区 | 久久久久久久无码高潮 | 国产成人精品在线 | 国产95在线 | 亚洲 | 日本绝伦老头与少妇在线观看 | 久久精品亚洲精品国产色婷 | 日韩www在线观看 | 日本免费一区二区三区中文字幕 | 久久婷婷久久一区二区三区 | 91亚洲精品国偷拍自产在线观看 | 99精品视频在线导航 | 1000部拍拍拍18勿入在线看 | 亚洲精品乱码久久久久久写真 | 国产又粗又猛又爽又黄的网站 | 久久久精品国产99久久精品麻追 | 波多野结衣在线视频免费观看 | 免费日韩一区二区 | 嫩草视频免费观看 | 国产精品福利视频推女郎 | 少妇裸体长淫交视频免费观看 | 日韩激情小说 | 欧美国产日韩亚洲中文 | zzijzzij日本成熟少妇 | 久久久久久久久毛片精品 | 91香蕉视频黄 | 精品伊人久久 | 性饥渴的农村熟妇 | 国产成人免费视频精品含羞草妖精 | 久久久亚洲成人 | 男人天堂av网 | 久久一级免费视频 | 操视频网站 | 国产高潮网站 | 欧美日韩麻豆 | 日日狠狠久久偷偷四色综合免费 | 一本无码久本草在线中文字幕dvd | 亚洲黄色大片 | 可以看污的网站 | 成午夜精品一区二区三区软件 | 亚洲视频中文字幕 | 日本高清在线一区二区三区 | 亚洲日韩欧美内射姐弟 | 黄色工厂这里只有精品 | 91久久偷偷做嫩草影院 | 日本一本视频 | 亚洲精品一区二区五月天 | 在线观看的av| 精品少妇久久久久久888优播 | 久久久人成影片免费观看 | 亚洲男人的天堂av | 日本午夜小视频 | 男人边吃奶边做好爽免费视频 | 国产吞精囗交免费视频网站 | 欧美网站在线观看 | 91pony九色| 欧美videos另类极品 | 特级黄色 一级播放 | 欧美日韩国产一区 | 国产色视频在线 | 欧美图片一区二区三区 | 日韩精品影视 | 国产精品www色诱视频 | 国产综合久久久久鬼色 | 国产精品普通话 | 国产黄在线观看免费观看不卡 | 成熟丰满熟妇高潮xxxxx | 男女无遮挡激情视频 | 男人影院在线观看 | 性猛交富婆╳xxx乱大交麻豆 | 国产成人福利 | 91麻豆欧美成人精品 | 极品美女啪啪 | 丁香社区五月天 | 黄视频在线 | 久久婷婷国产综合尤物精品 | 日本少妇作爱视频 | 男女做爰猛烈刺激 | 国产性―交―乱―色―情人 | 欧美精品一区二区久久 | 国产欲妇 | 9九色桋品熟女内射 | 午夜av片| 91大尺度| 日韩国产小视频 | 亚洲天堂首页 | 女人被狂躁60分钟视频 | 久久和欧洲码一码二码三码 | 51成人| 国产妇女乱一性一交 | 日本精品中文字幕 | 激情内射日本一区二区三区 | 色一情一交一乱一区二区 | gai免费观看网站外网 | 亚洲色大成网站www国产 | 国产成人无码综合亚洲日韩 | 中国女人裸体乱淫 | 欧洲成人综合 | a猛片免在新观看 | 国产无毛片 | 亚洲 欧美 国产 制服 动漫 | 欧美一区二区人人喊爽 | 国产ts丝袜人妖系列视频 | 99精品大学生啪啪自拍 | 老熟妇仑乱视频一区二区 | 你懂得国产| 成人18视频免费69 | 国产欧美激情日韩成人三区 | 91看片淫黄大片91桃色 | 揄拍成人国产精品视频 | ass日本丰满熟妇pics | 日本激情视频一区二区三区 | 2020久久超碰国产精品最新 | 天堂国产永久综合人亚洲欧美 | 免费一级肉体全黄毛片 | 成人动漫区 | 在线免费观看视频黄 | 中文字幕91视频 | 丰满饥渴的少妇hd | 国产精品久久久久久久免费看 | 中文字幕人妻少妇引诱隔壁 | 免费无码又爽又刺激高潮的视频 | 欧美日韩一区二区三区69堂 | 国产操女人 | 成人av免费| 久久精品久久精品久久 | 国产人人爱 | 国产精品无码不卡一区二区三区 | 麻豆黄色网址 | 国产精品资源在线观看 | 天堂av最新网址 | 国产精品久久久久一区二区 | 新版本天堂资源在线中文8的特点 | 俺来也俺来啦awww官网 | 中国大陆精品视频xxxx | 久久婷婷国产综合尤物精品 | 嫩草影院入口污在线 | a天堂最新版中文在线地址 a天堂最新地址 | 国产亚洲欧美日韩亚洲中文色 | 久久精品中文字幕大胸 | 91香蕉视频黄色 | 午夜h| 91成人在线免费视频 | 韩国无码av片在线观看网站 | 91欧美视频| 中文字幕一区二区精品 | 国产色视频一区二区三区 | 婷婷五月综合缴情在线视频 | 性感美女av在线 | 人妻熟妇女的欲乱系列 | 亚洲另类欧美综合久久图片区 | 欧美入口 | 真人做爰高潮全过程毛片 | 四虎影院免费 | 久久综合伊人 | 亚洲片在线观看 | 久久精品国产免费 | 岛国av大片| 新片速递丨最新合集bt伙计 | 人妻少妇无码精品视频区 | a天堂一码二码专区 | 久久99亚洲精品久久久久 | 欧美va天堂va视频va在线 | 国产一二三区免费视频 | 久久人人爽人人片 | 三八成人网 | 中文字幕一区二区三区四区五区 | 亚洲精品三级 | 日韩av图片 | 欧美激情一区二区三级高清视频 | 精品国产依人香蕉在线精品 | 自拍偷拍第5页 | 久久bb | 国内精品免费视频 | 久久狼人天堂 | 躁躁日日躁 | 五月亚洲综合 | 人人妻人人澡人人爽人人精品av | www豆豆成人网com | 亚洲自拍偷拍网站 | 美女100%视频免费观看 | 国产色综合久久无码有码 | 色老板av| 欧美激情综合色综合啪啪五月 | 日本人裸体做爰视频 | 久久国产精品久久久久久电车 | 久久人人爽爽爽人久久久 | av一二三 | 九九九在线 | 国产情侣一区二区三区 | 久久综合国产伦精品免费 | 日本在线视频www鲁啊鲁 | 99在线精品视频免费观看20 | 偷拍亚洲欧美 | 黄网站色视频免费观看 | 一区二区三区在线免费观看视频 | 女人下面流白浆的视频 | 欧美91精品久久久久国产性生爱 | 国产亚洲精品久久久久久无几年桃 | 国产成人精品微拍视频网址 | 久操成人 | 日韩内射美女人妻一区二区三区 | 国产情侣主伺候绿帽男m | 精品免费久久久久久久 | 豆国产95在线 | 亚洲 | 中文字幕有码在线播放 | 韩国bj大尺度vip福利网站 | 国产日韩欧美亚洲精品中字 | 久久国产综合 | 成人免费视频网站 | 色综合色综合久久综合频道88 | 日本老妇70sex另类 | 中文字幕乱码中文乱码51精品 | 无翼乌口工全彩无遮挡h全彩 | 欧美a视频| av无码免费永久在线观看 | 男人猛躁进女人免费播放 | avtt在线播放 | 国精品人妻无码一区二区三区喝尿 | 先锋影音男人 | 国产精品第一页在线观看 | 国产精品人妻熟女毛片av久 | 91久久精品一区 | 看片网址国产福利av中文字幕 | 欧美在线你懂的 | 美女爆吸乳羞羞免费网站妖精 | 亚洲区小说区图片区qvod | 伊人55yiren综合开心 | 久久尤物 | 久久精品国产v日韩v亚洲 | 国产精品无套内射迪丽热巴 | 色婷婷av一区二区三区大白胸 | 天天插夜夜 | 久久久国产一区二区三区 | 奇米一区二区三区四区久久 | 91久久精品一区二区 | 久久久无码精品亚洲日韩按摩 | 78国产伦精品一区二区三区 | 国产精品国产三级国产不产一地 | 国产精品视频免费在线观看 | 国产精品久久久久一区二区三区 | 久久99久久99精品蜜柚传媒 | 第一次破处视频 | 日韩综合无码一区二区 | 国产伦精品一区二区三区免费优势 | 亚洲精品中文字幕乱码三区 | 国产乱子伦在线观看 | 欧美乱妇高清无乱码免费 | 午夜视频在线播放 | 免费无码又爽又刺激网站 | 国产第一页浮力影院入口 | 国产喷白浆一区二区三区 | 全国最大成人网 | 国产精品视频在线观看 | 亚洲va欧美va国产综合剧情 | 欧美男生射精高潮视频网站 | 国内乱子对白免费在线 | 成人免费xxxxx在线视频 | 黑人3p波多野结衣在线观看 | 亚洲天堂网在线观看 | 啊轻点内射在线视频 | 高清不卡一区 | 思思久久99热只有频精品66 | 国产精品嫩草55av | 欧美成人一区二区三区四区 | 女人毛片a毛片久久人人 | 一区免费在线观看 | 国毛片| 久久久亚洲精华液精华液精华液 | 欧美三级网站在线观看 | 女人裸体特黄做爰的视频 | 手机在线观看免费av | 黑人巨大无码中文字幕无码 | 少妇无码av无码专区在线观看 | www夜夜操| 天天综合天天综合 | 少妇裸体性生交 | 国产成人无码a区在线观看视频 | 欧美三级一区二区三区 | 一区二区亚洲视频 | 成人3d动漫在线观看 | 亚洲精品国产福利 | 少妇啪啪姿势不断呻吟av | 国产成人高清在线 | 深夜视频在线观看 | 欧美a级理论片 | 91精品情国产情侣高潮对白文档 | 九九热精品视频 | 中文在线中文资源不卡无 | 九九久久久 | 久久影院综合精品 | 亚欧在线播放 | a级片视频网站 | 日本无遮挡大尺度床戏网站 | 亚洲精品欧美综合二区 | 中文字幕在线成人 | 一本一本久久a久久精品综合妖精 | 国产三级精品三级在线观看 | 日日橹狠狠爱欧美二区免费 | 亚洲精品久久久中文字幕痴女 | www.夜夜操| 久久妇女高潮喷水多 | 少妇浴室精油按摩2 | 日本亚洲色大成网站www久久 | 国产好大好紧好爽好湿视频唱戏 | 精品一区视频 | 2022国产成人精品视频人 | 日韩二区在线 | 中文精品一区二区 | 日本麻豆一区二区三区视频 | 中国老妇xxxx性开放 | 色图综合网 | 国产一区二区av在线 | 亚洲国产精品激情在线观看 | 丁香五香天综合情 | 久久久久人妻一区精品 | 国产欧美精品区一区二区三区 | 日韩中文字幕免费视频 | 性av网 | 福利一区在线观看 | 久久av一区二区三区亚洲 | 国产大陆亚洲精品国产 | 美女av在线播放 | 欧美午夜大片 | 在线不卡视频 | 国产在线观看网站 | 成人美女毛片 | 国产精品久久久久久影院8一贰佰 | 欧美国产影院 | 91麻豆产精品久久久久久夏晴子 | 成人精品一区日本无码网站 | 尹人成人网 | 香蕉久久国产av一区二区 | 国产原创中文av | 黄色综合网 | 色综合视频二区偷拍在线 | 一级片久久久久 | 精品国产第一国产综合精品 | 99久久日韩精品免费热麻豆美女 | 山村大伦淫第1部分阅读小说 | 永久av在线免费观看 | 亚洲国产精品网站 | 亚洲精品国产精品乱码不卡√香蕉 | 亚洲成av人在线观看网址 | 黑人粗硬进入过程视频 | 高清国产一区 | 久久久无码精品亚洲日韩蜜桃 | 亚洲精品一区二区 | 公妇乱淫1~6集全观看不了啦 | 精品欧洲av无码一区二区14 | 亚洲婷婷综合久久一本伊一区 | 91精品国产综合久久蜜臀 | 国产又粗又长又黄的视频 | 看片网站在线观看 | 精品中文字幕一区二区 | 色五月色开心色婷婷色丁香 | 欧美日韩在线视频 | 国产日韩欧美日韩 | 黄久久久 | 5566亚洲精华国产精华精华液 | 激情人妻另类人妻伦 | 色免费视频 | 免费一级淫片红桃视频 | 中国字幕一色哟哟 | 神马午夜伦理影院 | 日吊视频| 人妻av无码一区二区三区 | 亚洲成人免费观看 | 日本高清在线一区 | 8×8x8×8人成免费视频 | 久久久久久久久久久久久久免费看 | www.xxxx国产| 波多野结衣精品在线 | 大江大河第3部48集在线观看 | 亚洲操片 | 少妇9999九九九九在线观看 | 国产久久精品 | 精品a在线| 国产午夜一区二区三区 | 女人裸体偷拍全过程 | 懂色av噜噜一区二区三区av88 | 国产精品偷伦免费观看视频 | 看片免费黄在线观看入口 | 又爽又色禁片1000视频免费看 | 久久精品一区二区 | 欧美在线看片 | 国产最爽的乱淫视频媛 | 女人喷液抽搐高潮视频 | 无码国内精品人妻少妇蜜桃视频 | 日韩欧美视频在线 | 调教驯服丰满美艳麻麻在线视频 | 五月丁香六月综合av | 免费看成人aa片无码视频吃奶 | 一区二区视频免费看 | 川上奈美侵犯中文字幕在线 | 亚洲精品久久久久 | 欧美图片一区 | 国产91精品一区二区麻豆亚洲 | 免费无码的av片在线观看 | 久久综合综合久久综合 | 久久性色欲av免费精品观看 | 成人不卡视频 | 亚洲国产精品成人精品无码区在线 | 性精品| 日韩人妻精品无码一区二区三区 | 国产精品va在线观看无码 | 瑟瑟在线视频 | 久久久久久久99精品免费观看 | 午夜三级在线观看 | 亚洲97视频 | 亚洲精品一区二三区不卡 | 国产大片b站| 少妇大叫太大太爽受不了 | 720lu国产刺激无码 | 国产伦理一区二区 | 国产一精品一av一免费 | 美女的mm免费视频 | 色欲一区二区三区精品a片 四虎精品成人免费视频 | 色网综合| 在线观看免费毛片 | 毛片网站网址 | 在线网站av| 欧洲美女黑人粗性暴交 | www亚洲在线 | 国产精品久久久久久久久久久免费看 | 精品美女一区 | 久久久精品二区 | 亚洲最大成人综合网 | 国产最露的三级 | 中文字幕ipx696希岛あい | 成人亚洲网站 | 国产偷人爽久久久久久老妇app | 二宫光在线播放88av | 91精品婷婷国产综合久久蝌蚪 | 国产精品偷伦视频免费还看的 | 色婷婷久久久亚洲一区二区三区 | 永久免费无码av网站在线观看 | 99久久99久久精品免费看蜜桃 | 肉色超薄丝袜脚交69xx | 国产精品igao视频网免费播放 | 色噜| 成人羞羞视频免费看看 | 欧美色成人综合影院 | 久久人人爽人人爽人人片av高请 | 国产乱码卡一卡2卡三卡四 国产精品国产三级国产专区53 | 乱子伦视频在线看 | 日本高清视频在线www色 | 古风h啪肉禁欲 | 69sex久久精品国产麻豆 | 人鳝交video另类hd | 日韩精品一区二区三区免费视频 | 国产免费又色又爽粗视频 | 国产午夜大片 | 九色porny丨入口在线 | 欧美情爱视频 | 久久九九免费 | 日本精品视频一区二区三区四区 | 天堂在线视频网站 | av片免费看| 欧美日韩欧美 | 国产精品中文字幕在线 | 日本爽快片100色毛片视频 | 成人做爰www免费看视频网战 | 蜜桃av噜噜一区二区三区 | 欧美视频91 | 男人天堂网在线视频 | 日韩av在线播放观看 | 日本精品高清一区二区 | 永久黄网站色视频免费直播 | 国产精品扒开腿做爽爽爽视频 | 国产精品99久久99久久久动漫 | 日本a级老少配 | 中文在线资源新版8 | 老司机午夜免费福利 | 日韩爱爱视频 | 国产色精品久久人妻 | 青青在线视频观看 | 日本三级欧美三级人妇视频黑白配 | 国产欧美一区二区在线观看 | 男人边做边吃奶头视频 | 青青久在线视频 | 国产精品综合久久 | 可以免费看的黄色网址 | gav久久| 色综合色综合色综合色欲 | 国产精品 精品国内自产拍 日韩精品一区二区三区中文 | 自拍偷拍激情小说 | 1000部羞羞视频在线看视频 | 中文字幕高清免费日韩视频在线 | 欧洲国产伦久久久久久久 | www五月婷婷 | 91久久久久久久久久久久久 | 91国产丝袜播放在线 | 日韩一本之道一区中文字幕 | 午夜男人影院 | 天天鲁在视频在线观看 | 三上悠亚在线精品二区 | 天堂а√在线中文在线新版 | 国产大片内射1区2区 | 99re国产 | 美女黄18以下禁止观看 | 激情文学综合网 | 免费一区二区无码东京热 | 天天射中文 | 国产精品国产成人国产三级 | 早起邻居人妻奶罩太松av | 18处破外女出血在线 | 国产新婚夫妇白天做个爱 | 亚洲精品一区二区三区香蕉 | 大尺度av | 日韩久久精品一区二区 | 人人妻人人澡人人爽超污 | 国产情侣草莓视频在线 | 99久久人妻精品免费二区 | av在线免费播放网站 | 久久成人毛片 | 色婷婷激情网 | 国产精品视频999 | 少妇一级淫片bbb | va在线播放 | 99爱精品视频在线观看免费 | 久久99亚洲精品久久久久 | 精品人妻一区二区三区四区在线 | 四虎影视永久在线观看 | 亚洲人做受 | 91操碰| 国产一区二区不卡老阿姨 | 国产精品久久久久久久久久久久午衣片 | 欧美aaaaa| 国产女人18毛片水真多1 | 成人午夜av在线 | 日韩少妇高潮抽搐 | 久久不见久久见免费视频7 18禁黄久久久aaa片广濑美月 | 亚洲一区自拍 | 亚洲第3页 | 国产精品久久久久久亚洲影视 | 无码国模国产在线观看 | 丁香五月网久久综合 | 在线观看免费黄色av | 夜夜操网| 高清av免费 | 国产女人在线视频 | 成人在线国产视频 | 国产欧美日韩精品在线 | 蘑菇福利视频一区播放 | 亚洲精品av中文字幕在线 | 日本丶国产丶欧美色综合 | 亚州五月 | 一区二区在线观看免费视频 | 国产精品视频久久久久 | 色播视频在线观看 | 少妇高潮太爽了在线视频 | 国产精品午夜久久 | 777一区二区| 91视频插插插 | 亚洲国产精品成人午夜在线观看 | 日韩精品一区二区三区免费视频 | 欧美精品v | 国产免费网站在线观看 | va婷婷在线免费观看 | 真人作爱90分钟免费看视频 | 国产成人精品在线观看 | 日本免费色 | 精品久久人妻av中文字幕 | 欧美性生活在线视频 | 中国69av| 欧美精品videossex88 | 六月婷婷中文字幕 | 99精品国产在热久久婷婷 | 久久精品夜夜夜夜夜久久 | 自拍偷拍激情视频 | 成人午夜免费毛片 | 欧美三级影院 | 国产综合第一页 | 亚洲日韩中文字幕在线播放 | 唐人社导航福利精品 | 少妇沉沦哀羞迎合呻吟视频 | 日韩在线一区二区 | 日本电影一区二区三区 | 亚洲中字在线 | 欧美一区二区在线视频观看 | 欧美午夜一区二区福利视频 | 精品九九九| 日日爱影视 | 美女视频黄a视频全免费观看 | 粉嫩在线| 日本在线高清视频 | 香港a级毛片 | 成人免费观看视频网站 | 国产日产精品一区二区 | 9色视频| 调教大乳女仆喷奶水 |