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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android App包瘦身优化实践

發布時間:2024/7/5 Android 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android App包瘦身优化实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

隨著業務的快速迭代增長,美團App里不斷引入新的業務邏輯代碼、圖片資源和第三方SDK,直接導致APK體積不斷增長。包體積增長帶來的問題越來越多,如CDN流量費用增加、用戶安裝成功率降低,甚至可能會影響用戶的留存率。APK的瘦身已經是不得不考慮的事情。在嘗試瘦身的過程中,我們借鑒了很多業界其他公司提供的方案,同時也針對自身特點,發現了一些新的技巧。本文將對其中的一些做詳細介紹。

在開始講瘦身技巧之前,先來講一下APK的構成。

APK的構成

可以用Zip工具打開APK查看。比如,美團App 7.8.6的線上版本的格式是這樣的:

可以看到APK由以下主要部分組成:

文件/目錄描述
lib/存放so文件,可能會有armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips,大多數情況下只需要支持armabi與x86的架構即可,如果非必需,可以考慮拿掉x86的部分
res/存放編譯后的資源文件,例如:drawable、layout等等
assets/應用程序的資源,應用程序可以使用AssetManager來檢索該資源
META-INF/該文件夾一般存放于已經簽名的APK中,它包含了APK中所有文件的簽名摘要等信息
classes(n).dexclasses文件是Java Class,被DEX編譯后可供Dalvik/ART虛擬機所理解的文件格式
resources.arsc編譯后的二進制資源文件
AndroidManifest.xmlAndroid的清單文件,格式為AXML,用于描述應用程序的名稱、版本、所需權限、注冊的四大組件

當然還會有一些其它的文件,例如上圖中的org/、src/、push_version等文件或文件夾。這些資源是Java Resources,感興趣的可以結合編譯工作流中的流程圖以及MergeJavaResourcesTransform的源碼看看被打入APK包中的資源都有哪些,這里不做過多介紹。

在充分了解了APK各個組成部分以及它們的作用后,我們針對自身特點進行了分析和優化。下面將從Zip文件格式、classes.dex、資源文件、resources.arsc等方面來介紹下我們發現的部分優化技巧。

Zip格式優化

前面介紹了APK的文件格式以及主要組成部分,通過aapt l -v xxx.apk或unzip -l xxx.apk來查看APK文件時會得到以下信息,見下面截圖:

通過上圖可以看到APK中很多資源是以Stored來存儲的,根據Zip的文件格式中對壓縮方式的描述Compression_methods可以看出這些文件是沒有壓縮的,那為什么它們沒有被壓縮呢?從AAPT的源碼中找到以下描述:

/* these formats are already compressed, or don't compress well */ static const char* kNoCompressExt[] = {".jpg", ".jpeg", ".png", ".gif",".wav", ".mp2", ".mp3", ".ogg", ".aac",".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",".rtttl", ".imy", ".xmf", ".mp4", ".m4a",".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",".amr", ".awb", ".wma", ".wmv", ".webm", ".mkv" };

可以看出AAPT在資源處理時對這些文件后綴類型的資源是不做壓縮的,那是不是可以修改它們的壓縮方式從而達到瘦身的效果呢?

在介紹怎么做之前,先來大概介紹一下App的資源是怎么被打進APK包里的。Android構建工具鏈使用AAPT工具來對資源進行處理,來看下圖(圖片來源于Build Workflow):

通過上圖可以看到Manifest、Resources、Assets的資源經過AAPT處理后生成R.java、Proguard Configuration、Compiled Resources。其中R.java大家都比較熟悉,這里就不過多介紹了。我們來重點看看Proguard Configuration、Compiled Resources都是做什么的呢?

  • Proguard Configuration是AAPT工具為Manifest中聲明的四大組件以及布局文件中(XML layouts)使用的各種Views所生成的ProGuard配置,該文件通常存放在${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/proguard-rules/${flavorName}/${buildType}/aapt_rules.txt,下面是項目中該文件的截圖,紅框標記出來的就是對AndroidManifest.xml、XML Layouts中相關Class的ProGuard配置。

  • Compiled Resources是一個Zip格式的文件,這個文件的路徑通常為${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/res/resources-${flavorName}-${buildType}-stripped.ap_。 通過下面經過Zip解壓后的截圖,可以看出這個文件包含了res、AndroidManifest.xml和resources.arsc的文件或文件夾。結合Build Workflow中的描述,可以看出這個文件(resources-${flavorName}-${buildType}-stripped.ap_)會被apkbuilder打包到APK包中,它其實就是APK的“資源包”(res、AndroidManifest.xml和resources.arsc)。

我們就是通過這個文件來修改不同后綴文件資源的壓縮方式來達到瘦身效果的,而在后面“resources.arsc的優化”一節中也是操作的這個文件。

筆者在自己的項目中是通過在package${flavorName} Task(感興趣的同學可以查看源碼)之前進行這個操作的。

下面是部分代碼片段:

appPlugin.variantManager.variantDataList.each { variantData ->variantData.outputs.each {def sourceApFile = it.packageAndroidArtifactTask.getResourceFile();def destApFile = new File("${sourceApFile.name}.temp", sourceApFile.parentFile);it.packageAndroidArtifactTask.doFirst {byte[] buf = new byte[1024 * 8];ZipInputStream zin = new ZipInputStream(new FileInputStream(sourceApFile));ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destApFile));ZipEntry entry = zin.getNextEntry();while (entry != null) {String name = entry.getName();// Add ZIP entry to output stream.ZipEntry zipEntry = new ZipEntry(name);if (ZipEntry.STORED == entry.getMethod() && !okayToCompress(entry.getName())) {zipEntry.setMethod(ZipEntry.STORED)zipEntry.setSize(entry.getSize())zipEntry.setCompressedSize(entry.getCompressedSize())zipEntry.setCrc(entry.getCrc())} else {zipEntry.setMethod(ZipEntry.DEFLATED)...}...out.putNextEntry(zipEntry);out.closeEntry();entry = zin.getNextEntry();}// Close the streamszin.close();out.close();sourceApFile.delete();destApFile.renameTo(sourceApFile);}} }

當然也可以在其它構建步驟中采用更高壓縮率的方式來達到瘦身效果,例如采用7Zip壓縮等等。

本技巧的使用需要注意以下問題: * 如果音視頻資源被壓縮存放在APK中的話,在使用一些音頻、視頻API時尤其要注意,需要做好充分的測試。 * resources.arsc文件最好不要壓縮存儲,如果壓縮會影響一定的性能(尤其是冷啟動時間)。 * 如果想在Android 6.0上開啟android:extractNativeLibs=”false”的話,.so 文件也不能被壓縮,android:extractNativeLibs的使用姿勢看這里:App Manifest — application。

classes.dex的優化

如何優化classes.dex的大小呢?大體有如下套路:

  • 時刻保持良好的編程習慣和對包體積敏銳的嗅覺,去除重復或者不用的代碼,慎用第三方庫,選用體積小的第三方SDK等等。
  • 開啟ProGuard來進行代碼壓縮,通過使用ProGuard來對代碼進行混淆、優化、壓縮等工作。

針對第一種套路,因各個公司的項目的差異,共性的東西較少,需要case by case的分析,這里不做過多的介紹。

壓縮代碼

可以通過開啟ProGuard來實現代碼壓縮,可以在build.gradle文件相應的構建類型中添加minifyEnabled true。

請注意,代碼壓縮會拖慢構建速度,因此應該盡可能避免在調試構建中使用。不過一定要為用于測試的最終APK啟用代碼壓縮,如果不能充分地自定義要保留的代碼,可能會引入錯誤。

例如,下面這段來自build.gradle文件的代碼用于為發布構建啟用代碼壓縮:

android {buildTypes {release {minifyEnabled trueproguardFiles getDefaultProguardFile(‘proguard-android.txt'),'proguard-rules.pro'}}... }

除了minifyEnabled屬性外,還有用于定義ProGuard規則的proguardFiles屬性:

  • getDefaultProguardFile(‘proguard-android.txt')是從Android SDKtools/proguard/文件夾獲取默認ProGuard設置。
  • proguard-rules.pro文件用于添加自定義ProGuard規則。默認情況下,該文件位于模塊根目錄(build.gradle文件旁)。

提示:要想做進一步的代碼壓縮,可嘗試使用位于同一位置的proguard-android-optimize.txt文件。它包括相同的ProGuard規則,但還包括其他在字節碼一級(方法內和方法間)執行分析的優化,以進一步減小APK大小和幫助提高其運行速度。

在Gradle Plugin 2.2.0及以上版本ProGuard的配置文件會自動解壓縮到${rootProject.buildDir}/${AndroidProject.FD_INTERMEDIATES}/proguard-files/目錄下,proguardFiles會從這個目錄來獲取ProGuard配置。

每次執行完ProGuard之后,ProGuard都會在${project.buildDir}/outputs/mapping/${flavorDir}/生成以下文件:

文件名描述
dump.txtAPK中所有類文件的內部結構
mapping.txt提供原始與混淆過的類、方法和字段名稱之間的轉換,可以通過proguard.obfuscate.MappingReader來解析
seeds.txt列出未進行混淆的類和成員
usage.txt列出從APK移除的代碼

可以通過在usage.txt文件中看到哪些代碼被刪除了,如下圖中所示android.support.multidex.MultiDex已經被刪除了:

R Field的優化

除了對項目代碼優化和開啟代碼壓縮之外,筆者在《美團Android DEX自動拆包及動態加載簡介》這篇文章中提到了通過內聯R Field來解決R Field過多導致MultiDex 65536的問題,而這一步驟對代碼瘦身能夠起到明顯的效果。下面是筆者通過字節碼工具在構建流程中內聯R Field的代碼片段(字節碼的修改可以使用Javassist或者ASM,該步驟筆者采用的是Javassist)。

ctBehaviors.each { CtBehavior ctBehavior ->if (!ctBehavior.isEmpty()) {try {ctBehavior.instrument(new ExprEditor() {@Overridepublic void edit(FieldAccess f) {try {def fieldClassName = JavassistUtils.getClassNameFromCtClass(f.getCtClass())if (shouldInlineRField(className, fieldClassName) && f.isReader()) {def temp = fieldClassName.substring(fieldClassName.indexOf(ANDROID_RESOURCE_R_FLAG) + ANDROID_RESOURCE_R_FLAG.length())def fieldName = f.fieldNamedef key = "${temp}.${fieldName}"if (resourceSymbols.containsKey(key)) {Object obj = resourceSymbols.get(key)try {if (obj instanceof Integer) {int value = ((Integer) obj).intValue()f.replace("\$_=${value};")} else if (obj instanceof Integer[]) {def obj2 = ((Integer[]) obj)StringBuilder stringBuilder = new StringBuilder()for (int index = 0; index < obj2.length; ++index) {stringBuilder.append(obj2[index].intValue())if (index != obj2.length - 1) {stringBuilder.append(",")}}f.replace("\$_ = new int[]{${stringBuilder.toString()}};")} else {throw new GradleException("Unknown ResourceSymbols Type!")}} catch (NotFoundException e) {throw new GradleException(e.message)} catch (CannotCompileException e) {throw new GradleException(e.message)}} else {throw new GradleException("******** InlineRFieldTask unprocessed ${className}, ${fieldClassName}, ${f.fieldName}, ${key}")}}} catch (NotFoundException e) {}}})} catch (CannotCompileException e) {}} }

其它優化手段

針對代碼的瘦身還有很多優化的技巧,例如:

  • 減少ENUM的使用(詳情可以參考:Remove Enumerations),每減少一個ENUM可以減少大約1.0到1.4 KB的大小;
  • 通過pmd cpd來檢查重復的代碼從而進行代碼優化;
  • 移除掉所有無用或者功能重復的依賴庫。

這些優化技巧就不展開介紹了。

資源的優化

圖片優化

為了支持Android設備DPI的多樣化([l|m|tv|h|x|xx|xxx]dpi)以及用戶對高質量UI的期待,美團App中使用了大量的圖片,在Android下支持很多格式的圖片,例如:PNG、JPG 、WebP,那我們該怎么選擇不同類型的圖片格式呢? 在Google I/O 2016中提到了針對圖片格式的選擇,來看下圖(圖片來源于Image compression for Android developers):

通過上圖可以看出一個大概圖片格式選擇的方法。如果能用VectorDrawable來表示的話優先使用VectorDrawable,如果支持WebP則優先用WebP,而PNG主要用在展示透明或者簡單的圖片,而其它場景可以使用JPG格式。針對每種圖片格式也有各類的優化手段和優化工具。

使用矢量圖片

可以使用矢量圖形來創建獨立于分辨率的圖標和其他可伸縮圖片。使用矢量圖片能夠有效的減少App中圖片所占用的大小,矢量圖形在Android中表示為VectorDrawable對象。 使用VectorDrawable對象,100字節的文件可以生成屏幕大小的清晰圖像,但系統渲染每個VectorDrawable對象需要大量的時間,較大的圖像需要更長的時間才能出現在屏幕上。 因此只有在顯示小圖像時才考慮使用矢量圖形。有關使用VectorDrawable的更多信息,請參閱 Working with Drawables。

使用WebP

如果App的minSdkVersion高于14(Android 4.0+)的話,可以選用WebP格式,因為WebP在同畫質下體積更小(WebP支持透明度,壓縮比比JPEG更高但顯示效果卻不輸于JPEG,官方評測quality參數等于75均衡最佳), 可以通過PNG到WebP轉換工具來進行轉換。當然Android從4.0才開始WebP的原生支持,但是不支持包含透明度,直到Android 4.2.1+才支持顯示含透明度的WebP,在筆者使用中是判斷當前App的minSdkVersion以及圖片文件的類型(是否為透明)來選用是否適用WebP。見下面的代碼片段:

boolean isPNGWebpConvertSupported() {if (!isWebpConvertEnable()) {return false}// Android 4.0+return GradleUtils.getAndroidExtension(project).defaultConfig.minSdkVersion.apiLevel >= 14// 4.0 }boolean isTransparencyPNGWebpConvertSupported() {if (!isWebpConvertEnable()) {return false}// Lossless, Transparency, Android 4.2.1+return GradleUtils.getAndroidExtension(project).defaultConfig.minSdkVersion.apiLevel >= 18// 4.3 }def convert() {String resPath = "${project.buildDir}/${AndroidProject.FD_INTERMEDIATES}/res/merged/${variant.dirName}"def resDir = new File("${resPath}")resDir.eachDirMatch(~/drawable[a-z0-9-]*/) { dir ->FileTree tree = project.fileTree(dir: dir)tree.filter { File file ->return (isJPGWebpConvertSupported() && (file.name.endsWith(SdkConstants.DOT_JPG) || file.name.endsWith(SdkConstants.DOT_JPEG))) || (isPNGWebpConvertSupported() && file.name.endsWith(SdkConstants.DOT_PNG) && !file.name.endsWith(SdkConstants.DOT_9PNG))}.each { File file ->def shouldConvert = trueif (file.name.endsWith(SdkConstants.DOT_PNG)) {if (!isTransparencyPNGWebpConvertSupported()) {shouldConvert = !Imaging.getImageInfo(file).isTransparent()}}if (shouldConvert) {WebpUtils.encode(project, webpFactorQuality, file.absolutePath, webp)}}} }

選擇更優的壓縮工具

可以使用pngcrush、pngquant或zopflipng等壓縮工具來減少PNG文件大小,而不會丟失圖像質量。所有這些工具都可以減少PNG文件大小,同時保持圖像質量。

pngcrush工具特別有效:此工具在PNG過濾器和zlib(Deflate)參數上迭代,使用過濾器和參數的每個組合來壓縮圖像。然后選擇產生最小壓縮輸出的配置。

對于JPEG文件,你可以使用packJPG或guetzli等工具將JPEG文件壓縮的更小,這些工具能夠在保持圖片質量不變的情況下,把圖片文件壓縮的更小。guetzli工具更是能夠在圖片質量不變的情況下,將文件大小降低35%。

在Android構建流程中AAPT會使用內置的壓縮算法來優化res/drawable/目錄下的PNG圖片,但也可能會導致本來已經優化過的圖片體積變大,可以通過在build.gradle中設置cruncherEnabled來禁止AAPT來優化PNG圖片。

aaptOptions {cruncherEnabled = false }

開啟資源壓縮

Android的編譯工具鏈中提供了一款資源壓縮的工具,可以通過該工具來壓縮資源,如果要啟用資源壓縮,可以在build.gradle文件中將shrinkResources true。例如:

android {...buildTypes {release {shrinkResources trueminifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'}} }

需要注意的是目前資源壓縮器目前不會移除values/文件夾中定義的資源(例如字符串、尺寸、樣式和顏色),有關詳情,請參閱問題 70869。

Android構建工具是通過ResourceUsageAnalyzer來檢查哪些資源是無用的,當檢查到無用的資源時會把該資源替換成預定義的版本。詳看下面代碼片段(摘自com.android.build.gradle.tasks.ResourceUsageAnalyzer):

public class ResourceUsageAnalyzer {.../*** Whether we should create small/empty dummy files instead of actually* removing file resources. This is to work around crashes on some devices* where the device is traversing resources. See http://b.android.com/79325 for more.*/public static final boolean REPLACE_DELETED_WITH_EMPTY = true;// A 1x1 pixel PNG of type BufferedImage.TYPE_BYTE_GRAYpublic static final byte[] TINY_PNG = new byte[] {(byte)-119, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10,(byte) 26, (byte) 10, (byte) 0, (byte) 0, (byte) 0, (byte) 13,(byte) 73, (byte) 72, (byte) 68, (byte) 82, (byte) 0, (byte) 0,(byte) 0, (byte) 1, (byte) 0, (byte) 0, (byte) 0, (byte) 1,(byte) 8, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 58,(byte) 126, (byte)-101, (byte) 85, (byte) 0, (byte) 0, (byte) 0,(byte) 10, (byte) 73, (byte) 68, (byte) 65, (byte) 84, (byte) 120,(byte) -38, (byte) 99, (byte) 96, (byte) 0, (byte) 0, (byte) 0,(byte) 2, (byte) 0, (byte) 1, (byte) -27, (byte) 39, (byte) -34,(byte) -4, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 73,(byte) 69, (byte) 78, (byte) 68, (byte) -82, (byte) 66, (byte) 96,(byte)-126};public static final long TINY_PNG_CRC = 0x88b2a3b0L;// A 3x3 pixel PNG of type BufferedImage.TYPE_INT_ARGB with 9-patch markerspublic static final byte[] TINY_9PNG = new byte[] {(byte)-119, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10,(byte) 26, (byte) 10, (byte) 0, (byte) 0, (byte) 0, (byte) 13,(byte) 73, (byte) 72, (byte) 68, (byte) 82, (byte) 0, (byte) 0,(byte) 0, (byte) 3, (byte) 0, (byte) 0, (byte) 0, (byte) 3,(byte) 8, (byte) 6, (byte) 0, (byte) 0, (byte) 0, (byte) 86,(byte) 40, (byte) -75, (byte) -65, (byte) 0, (byte) 0, (byte) 0,(byte) 20, (byte) 73, (byte) 68, (byte) 65, (byte) 84, (byte) 120,(byte) -38, (byte) 99, (byte) 96, (byte)-128, (byte)-128, (byte) -1,(byte) 12, (byte) 48, (byte) 6, (byte) 8, (byte) -96, (byte) 8,(byte)-128, (byte) 8, (byte) 0, (byte)-107, (byte)-111, (byte) 7,(byte) -7, (byte) -64, (byte) -82, (byte) 8, (byte) 0, (byte) 0,(byte) 0, (byte) 0, (byte) 0, (byte) 73, (byte) 69, (byte) 78,(byte) 68, (byte) -82, (byte) 66, (byte) 96, (byte)-126};public static final long TINY_9PNG_CRC = 0x1148f987L;// The XML document <x/> as binary-packed with AAPTpublic static final byte[] TINY_XML = new byte[] {(byte) 3, (byte) 0, (byte) 8, (byte) 0, (byte) 104, (byte) 0,(byte) 0, (byte) 0, (byte) 1, (byte) 0, (byte) 28, (byte) 0,(byte) 36, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0,(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,(byte) 0, (byte) 1, (byte) 0, (byte) 0, (byte) 32, (byte) 0,(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 1,(byte) 120, (byte) 0, (byte) 2, (byte) 1, (byte) 16, (byte) 0,(byte) 36, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0,(byte) 0, (byte) 0, (byte) -1, (byte) -1, (byte) -1, (byte) -1,(byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) 0, (byte) 0,(byte) 0, (byte) 0, (byte) 20, (byte) 0, (byte) 20, (byte) 0,(byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,(byte) 0, (byte) 0, (byte) 3, (byte) 1, (byte) 16, (byte) 0,(byte) 24, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0,(byte) 0, (byte) 0, (byte) -1, (byte) -1, (byte) -1, (byte) -1,(byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) 0, (byte) 0,(byte) 0, (byte) 0};public static final long TINY_XML_CRC = 0xd7e65643L;... }

上面截圖中3個byte數組的定義就是資源壓縮工具為無用資源提供的預定義版本,可以看出對.png提供了TINY_PNG, 對.9.png提供了TINY_9PNG以及對.xml提供了TINY_XML的預定義版本。

資源壓縮工具的詳細使用可以參考Shrink Your Code and Resources。資源壓縮工具默認是采用安全壓縮模式來運行,可以通過開啟嚴格壓縮模式來達到更好的瘦身效果。

如果想知道哪些資源是無用的,可以通過資源壓縮工具的輸出日志文件${project.buildDir}/outputs/mapping/release/resources.txt來查看。如下圖所示res/layout/abc_activity_chooser_viewer.xml就是無用的,然后被預定義的版本TINY_XML所替換:

資源壓縮工具只是把無用資源替換成預定義較小的版本,那我們如何刪除這些無用資源呢?通常的做法是結合資源壓縮工具的輸出日志,找到這些資源并把它們進行刪除。但在筆者的項目中很多無用資源是被其它組件或第三方SDK所引入的,如果采用這種優化方式會帶來這些SDK后期維護成本的增加,針對這種情況筆者是通過采用在resources.arsc中做優化來解決的,詳情看下面“resources.arsc的優化”一節的介紹。

語言資源優化

根據App自身支持的語言版本選用合適的語言資源,例如使用了AppCompat,如果不做任何配置的話,最終APK包中會包含AppCompat中消息的所有已翻譯語言字符串,無論應用的其余部分是否翻譯為同一語言,可以通過resConfig來配置使用哪些語言,從而讓構建工具移除指定語言之外的所有資源。下圖是具體的配置示例:

android {...defaultConfig {...resConfigs "zh", "zh-rCN"}... }

針對為不同DPI所提供的圖片也可以采用相同的策略,需要針對自身的目標用戶和目標設備做一定的選擇,可以參考Support Only Specific Densities來操作。有關屏幕密度的詳細信息,請參閱Screen Sizes and Densities。

對.so文件也可以采用類似的策略,比如筆者的項目中只保留了armeabi版本的.so文件。

resources.arsc的優化

針對resources.arsc,筆者嘗試過的優化手段如下:

  • 開啟資源混淆;
  • 對重復的資源進行優化;
  • 對被shrinkResources優化掉的資源進行處理。

下面將分別對這些優化手段進行展開介紹。

資源混淆

在筆者另一篇《美團Android資源混淆保護實踐》文章中介紹了采用對資源混淆的方式來保護資源的安全,同時也提到了這種方式有顯著的瘦身效果。筆者當時是采用修改AAPT的相關源碼的方式,這種方式的痛點是每次升級Build Tools都要修改一次AAPT源碼,維護性較差。目前筆者采用了微信開源的資源混淆庫AndResGuard,具體的原理和使用幫助可以參考安裝包立減1M–微信Android資源混淆打包工具。

無用資源優化

在上一節中介紹了可以通過shrinkResources true來開啟資源壓縮,資源壓縮工具會把無用的資源替換成預定義的版本而不是移除,如果采用人工移除的方式會帶來后期的維護成本,這里筆者采用了一種比較取巧的方式,在Android構建工具執行package${flavorName}Task之前通過修改Compiled Resources來實現自動去除無用資源。

具體流程如下:

  • 收集資源包(Compiled Resources的簡稱)中被替換的預定義版本的資源名稱,通過查看資源包(Zip格式)中每個ZipEntry的CRC-32 checksum來尋找被替換的預定義資源,預定義資源的CRC-32定義在ResourceUsageAnalyzer,下面是它們的定義。
// A 1x1 pixel PNG of type BufferedImage.TYPE_BYTE_GRAYpublic static final long TINY_PNG_CRC = 0x88b2a3b0L;// A 3x3 pixel PNG of type BufferedImage.TYPE_INT_ARGB with 9-patch markerspublic static final long TINY_9PNG_CRC = 0x1148f987L;// The XML document <x/> as binary-packed with AAPTpublic static final long TINY_XML_CRC = 0xd7e65643L;
  • 通過android-chunk-utils把resources.arsc中對應的定義移除;
  • 刪除資源包中對應的資源文件。

重復資源優化

目前美團App是由各個業務團隊共同開發完成,為了方便各業務團隊的獨立開發,美團App進行了平臺化改造。改造時存在很多資源文件(如:drawable、layout等)被不同的業務團隊都拷貝到自己的Library下,同時為了避免引發資源覆蓋的問題,每個業務團隊都會為自己的資源文件名添加前綴。這樣就導致了這些資源文件雖然內容相同,但因為名稱的不同而不能被覆蓋,最終都會被集成到APK包中,針對這種問題筆者采用了和前面“無用資源優化”一節中描述類似的策略。

具體步驟如下:

  • 通過資源包中的每個ZipEntry的CRC-32 checksum來篩選出重復的資源;
  • 通過android-chunk-utils修改resources.arsc,把這些重復的資源都重定向到同一個文件上;
  • 把其它重復的資源文件從資源包中刪除。

代碼片段:

variantData.outputs.each {def apFile = it.packageAndroidArtifactTask.getResourceFile();it.packageAndroidArtifactTask.doFirst {def arscFile = new File(apFile.parentFile, "resources.arsc");JarUtil.extractZipEntry(apFile, "resources.arsc", arscFile);def HashMap<String, ArrayList<DuplicatedEntry>> duplicatedResources = findDuplicatedResources(apFile);removeZipEntry(apFile, "resources.arsc");if (arscFile.exists()) {FileInputStream arscStream = null;ResourceFile resourceFile = null;try {arscStream = new FileInputStream(arscFile);resourceFile = ResourceFile.fromInputStream(arscStream);List<Chunk> chunks = resourceFile.getChunks();HashMap<String, String> toBeReplacedResourceMap = new HashMap<String, String>(1024);// 處理arsc并刪除重復資源Iterator<Map.Entry<String, ArrayList<DuplicatedEntry>>> iterator = duplicatedResources.entrySet().iterator();while (iterator.hasNext()) {Map.Entry<String, ArrayList<DuplicatedEntry>> duplicatedEntry = iterator.next();// 保留第一個資源,其他資源刪除掉for (def index = 1; index < duplicatedEntry.value.size(); ++index) {removeZipEntry(apFile, duplicatedEntry.value.get(index).name);toBeReplacedResourceMap.put(duplicatedEntry.value.get(index).name, duplicatedEntry.value.get(0).name);}}for (def index = 0; index < chunks.size(); ++index) {Chunk chunk = chunks.get(index);if (chunk instanceof ResourceTableChunk) {ResourceTableChunk resourceTableChunk = (ResourceTableChunk) chunk;StringPoolChunk stringPoolChunk = resourceTableChunk.getStringPool();for (def i = 0; i < stringPoolChunk.stringCount; ++i) {def key = stringPoolChunk.getString(i);if (toBeReplacedResourceMap.containsKey(key)) {stringPoolChunk.setString(i, toBeReplacedResourceMap.get(key));}}}}} catch (IOException ignore) {} catch (FileNotFoundException ignore) {} finally {if (arscStream != null) {IOUtils.closeQuietly(arscStream);}arscFile.delete();arscFile << resourceFile.toByteArray();addZipEntry(apFile, arscFile);}}} }

通過這種方式可以有效減少重復資源對包體大小的影響,同時這種操作方式對各業務團隊透明,也不會增加協調相同資源如何被不同業務團隊復用的成本。

總結

上述就是我們目前在APK瘦身方面的做的一些嘗試和積累,可以根據自身情況取舍使用。當然我們還可以采取一些按需加載的策略來減少安裝包的體積。最后提一點,砍掉不必要的功能才是安裝包瘦身的超級大招。一個好的App的標準有很多方面,但提供盡可能小的安裝包是其中一個重要的方面,這也是對我們Android開發者人員自身的提出的基本要求,要時刻保持良好的編程習慣和對包體積敏銳的嗅覺。

參考文獻

  • Android application package (APK)
  • Zip (file format)
  • Build Workflow
  • Android AAPT Source Code
  • Reduce APK Size
  • Shrink Your Code and Resources
  • Manage Your App’s Memory
  • Vector Drawable
  • Javassist
  • ASM
  • pngcrush
  • pngquant
  • zopflipng
  • android-chunk-utils
  • 安裝包立減1M–微信Android資源混淆打包工具
  • 減少 APK 的大小,Android 官方這樣說
  • Google I/O 2016 筆記:APK 瘦身的正確姿勢

作者簡介

建帥,Android技術專家,2015年3月加入美團,目前就職于到店餐飲技術部信息與交易技術中心。

到店餐飲技術部交易與信息技術中心,負責美團美食用戶端業務,服務于數以億計用戶,通過更好的榜單、真實的評價和完善的信息為用戶提供更好的決策支持,致力于提升用戶體驗;同時承載所有餐飲商戶端線上流量,為餐飲商戶提供多種營銷工具,提升餐飲商戶營銷效率,最終達到讓國人“Eat Better、Live Better”的美好愿景!我們的團隊包含且不限于Android、iOS、FE、Java、PHP等技術方向,已完備覆蓋前后端技術棧。只要你來,就能點亮全棧開發技能樹。

總結

以上是生活随笔為你收集整理的Android App包瘦身优化实践的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

午夜国产影院 | 天天干,夜夜爽 | 婷婷激情av| 免费视频二区 | 97精品国产97久久久久久久久久久久 | 日韩在线免费 | 中文字幕av全部资源www中文字幕在线观看 | 欧美精品小视频 | 国产精品一区二区精品视频免费看 | 久久人人97超碰精品888 | 五月婷婷影院 | 成年人免费电影在线观看 | 国产永久免费 | 中文字幕av全部资源www中文字幕在线观看 | 久久久网址 | 国产精品久久久久久影院 | 欧美亚洲精品在线观看 | 国产精品成人在线 | 激情欧美xxxx | 欧美日韩18 | 人人艹视频 | 久久精品99国产 | 久色伊人 | 亚洲欧美日韩一二三区 | 九月婷婷色 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 色网站在线观看 | 国产美女网站视频 | 成人午夜精品 | 99精品免费久久久久久久久日本 | 中文字幕在线资源 | 久久尤物电影视频在线观看 | 国产日韩精品在线观看 | 日韩免费观看一区二区 | 九九九九精品 | 久操操| 国内亚洲精品 | 国产精在线 | 久久人人爽| 久草在线精品观看 | 久久成年人视频 | 成片免费观看视频999 | 久久噜噜少妇网站 | 香蕉视频国产在线观看 | 狠狠色丁香婷婷综合橹88 | 久久精品91久久久久久再现 | 精品国自产在线观看 | 国产高清 不卡 | 久草热视频 | 成人国产精品久久久久久亚洲 | 麻豆极品 | 最新精品国产 | 久久精品一区 | 成人毛片一区 | 国产 日韩 欧美 在线 | 国产精品麻豆果冻传媒在线播放 | 精品久久久久久亚洲综合网 | 国产精品av免费观看 | 青青草国产精品视频 | 国产精品毛片久久久久久久久久99999999 | 在线观看你懂的网址 | 国产手机视频在线 | 精品国产综合区久久久久久 | 日本色小说视频 | 久久试看 | 精品久久电影 | 国产精品美女毛片真酒店 | 久久艹综合 | 亚洲精品一区二区三区新线路 | 久久99精品国产99久久6尤 | 久久久久久蜜桃一区二区 | 五月天中文在线 | 色综合色综合色综合 | 久久久久久久久综合 | 日韩成人免费在线观看 | 亚洲专区 国产精品 | 亚洲视频精选 | 9在线观看免费高清完整 | 国产区在线视频 | 色婷婷97 | 最近中文字幕视频完整版 | 看av免费网站 | 久久精品99国产精品酒店日本 | 欧美a视频| 黄色电影网站在线观看 | www色婷婷com | 欧美激情视频一区二区三区免费 | 国产又粗又猛又黄又爽的视频 | 久草热视频| 国产精品成人一区二区三区吃奶 | 亚洲日日夜夜 | 日韩中文字幕免费 | 色中文字幕在线观看 | av高清一区 | 国产精品美女久久久久久久久 | 亚洲一级黄色片 | 欧美日韩性视频在线 | 91精品国产欧美一区二区 | 色综合久久综合网 | a在线观看免费视频 | 国产成人精品999在线观看 | 在线观看视频中文字幕 | 成人黄色大片网站 | 九九视频在线观看视频6 | 在线观看小视频 | 久久精品国产第一区二区三区 | 欧美精品久久久久久久免费 | 在线av资源 | 97视频久久久 | 久久 精品一区 | 欧美一区二区三区激情视频 | 五月综合| 国产v在线 | 欧美色插 | 精品国产一区二区三区久久 | 国产在线精品国自产拍影院 | 伊人www22综合色 | 欧美视频www | 97在线观 | 特级黄色电影 | 视频二区在线 | 国产精品videoxxxx | 91日韩在线播放 | 正在播放国产一区 | 中文区中文字幕免费看 | 午夜久久久久久久久久久 | 99热国产在线 | 久久久国际精品 | 精品国偷自产在线 | 日韩网页 | 婷婷丁香六月 | 国产综合激情 | 一区二区不卡在线观看 | 激情文学丁香 | 激情图片qvod | 亚洲成av人片在线观看无 | 欧美日韩免费一区二区 | 成年人在线观看 | 99久久日韩精品免费热麻豆美女 | 国内一区二区视频 | 婷婷在线网站 | av在线超碰 | 97在线观看免费 | 97精品久久 | 亚洲精品五月 | 亚洲精品久久久久久久蜜桃 | 亚洲欧美综合 | 最近能播放的中文字幕 | 又色又爽的网站 | 欧美日韩高清一区二区 | 精品专区一区二区 | www久久com| 中文字幕日韩高清 | 色网站在线看 | 欧美淫aaa免费观看 日韩激情免费视频 | 久久久久综合精品福利啪啪 | 中文字幕在线视频网站 | 久久刺激视频 | 视频91 | 视频一区在线免费观看 | 色网av| 亚洲精品资源在线观看 | 日韩在线电影一区 | 91热视频在线观看 | 在线国产91| 色综合久久五月天 | 精品一区二区视频 | 天堂网av 在线 | 午夜精品一区二区三区在线观看 | 久草在线资源观看 | 亚洲精品国产综合99久久夜夜嗨 | 亚洲国产精品久久久久婷婷884 | 日韩视频免费在线观看 | 日韩视频在线不卡 | 91在线视频 | 国产福利在线免费观看 | 伊人手机在线 | av丁香 | 麻豆综合网 | 亚洲欧洲精品视频 | 狠狠色丁香婷婷综合基地 | 永久免费视频国产 | 免费在线观看av的网站 | 国产精品淫片 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 国产精品不卡av | 亚洲视频精品在线 | 国产精品中文久久久久久久 | 国产一级二级三级在线观看 | 九九久久久久99精品 | 国产.精品.日韩.另类.中文.在线.播放 | 成人在线免费视频观看 | 国产视频2区 | 一本到视频在线观看 | 成人毛片100免费观看 | 青青河边草免费观看 | 91视频3p | 13日本xxxxxⅹxxx20 | 国产成人在线看 | 又爽又黄又刺激的视频 | zzijzzij亚洲日本少妇熟睡 | 久久免费av电影 | 久久99精品久久久久久秒播蜜臀 | 午夜精品久久久久久久久久久久久久 | 精品久久网站 | 97超碰中文字幕 | 99热在线这里只有精品 | 青草草在线 | 少妇精品久久久一区二区免费 | 国产亚洲精品久久久久久网站 | 亚洲国产中文字幕 | 99视频在线免费看 | 精品国产成人av | 国内揄拍国内精品 | 揉bbb玩bbb少妇bbb| 91麻豆精品国产91久久久久久久久 | 伊人网综合在线观看 | 色综合综合 | 国产黄色片免费 | 亚洲国产午夜视频 | 亚洲极色 | 一级黄网| 久久久久久久久久久久av | 国产一级淫片在线观看 | 天天插天天色 | 亚洲国产精品成人av | 99超碰在线观看 | 国产一级特黄毛片在线毛片 | 日日夜夜草 | 国产午夜精品久久久久久久久久 | 丁香花中文字幕 | 日韩电影在线视频 | 丁香婷婷基地 | 天天干天天草 | 超碰在线成人 | a国产精品 | 在线视频一区观看 | 日韩在线观看视频中文字幕 | 成人h动漫在线看 | 日韩午夜三级 | 亚洲成人精品av | 97电影院网 | 日韩欧美精品一区二区三区经典 | 成人免费一级 | 美女网站黄在线观看 | 91天堂在线观看 | 欧美男同视频网站 | 国精产品999国精产品视频 | 中文字幕 在线 一 二 | 亚洲综合国产精品 | 在线播放国产一区二区三区 | 免费成视频 | 亚洲丁香日韩 | 一区二区三区手机在线观看 | 亚洲精品理论 | 4p变态网欧美系列 | 岛国精品一区二区 | 黄色av一区二区三区 | 欧美夫妻性生活电影 | 中文字幕免费一区二区 | 精品国产观看 | 日本中文在线观看 | 国产不卡在线视频 | av在线播放观看 | 亚洲午夜电影网 | 日韩欧美视频在线观看免费 | 精品一区二区免费视频 | 日日干av| 中文字幕在线播放日韩 | 国产网站色 | 久草在线最新视频 | 五月天网站在线 | 成人av免费在线 | 日韩激情一二三区 | 麻豆91在线看 | 深爱五月激情网 | 成人中文字幕av | 国产精品视频地址 | 久久精品日本啪啪涩涩 | 在线观看国产永久免费视频 | 免费观看黄色12片一级视频 | 久久综合九色 | 欧美极品久久 | 精品久久国产 | 日韩一区二区三区视频在线 | 在线精品观看 | 欧美视频在线二区 | 综合网天天 | 久久精品男人的天堂 | 天天干天天射天天爽 | 亚洲人人网 | 国产69精品久久久久久 | 黄色午夜网站 | 久久综合九色综合欧美就去吻 | 国产视频18 | 日韩视频欧美视频 | 日韩免费在线视频 | 国产在线2020 | 久久一区二区免费视频 | 91精品网站 | 99久久精品国产亚洲 | 精品在线观看国产 | 国产精品国产自产拍高清av | 久久亚洲精品电影 | 久久综合九色综合97_ 久久久 | 久久高清免费观看 | 久久在现视频 | 人人狠狠| 日本黄色免费在线观看 | 国产精品美女www爽爽爽视频 | 国产高清在线永久 | 国产专区在线视频 | 日日干精品 | 国产又粗又长又硬免费视频 | 久久国产精品免费 | 亚洲天堂网在线视频 | 狠狠gao| av夜夜操| 狠狠色丁香婷婷综合久小说久 | 99日精品 | 欧美 日韩 国产 中文字幕 | 亚洲综合色播 | 国产精品乱码久久久久久1区2区 | 国产精品美女毛片真酒店 | 精品在线不卡 | 午夜色大片在线观看 | 亚洲欧美国产精品久久久久 | 久久免费看av | 最近高清中文在线字幕在线观看 | 欧美精品久久久久久久久久白贞 | 亚洲五月婷| 国产精品麻豆果冻传媒在线播放 | 精选久久 | 粉嫩一二三区 | 亚洲免费激情 | 91高清完整版在线观看 | 手机在线中文字幕 | av中文字幕在线播放 | 国产一区精品在线观看 | 99成人在线视频 | 九九热免费观看 | 亚洲午夜久久久久久久久 | 亚洲热久久 | 欧美激情va永久在线播放 | 亚洲电影院 | 亚洲欧洲精品一区二区精品久久久 | 欧美日韩亚洲精品在线 | 久久久久免费网 | 在线观看第一页 | 最近在线中文字幕 | 久久你懂得 | 日韩在线观看视频中文字幕 | 国内久久精品视频 | 久久久精品欧美一区二区免费 | 国产午夜视频在线观看 | 欧美日韩中文字幕在线视频 | 免费看的黄色录像 | 久久激情影院 | 99精品黄色| 国产极品尤物在线 | 欧美日韩天堂 | 国产99久久久久久免费看 | 中文字幕 在线看 | 日本aa在线 | 日本大片免费观看在线 | 亚洲视频在线观看网站 | 国产在线国偷精品产拍免费yy | 欧美一区免费在线观看 | 中文字幕中文字幕在线中文字幕三区 | 日韩高清久久 | 国产精品一区二区在线观看免费 | 五月婷婷色综合 | 国产黄色高清 | 久久久人人爽 | 日韩免费视频在线观看 | 成年人视频在线 | 精品在线99 | 人人爽人人爽人人 | www亚洲视频 | 国产一区国产二区在线观看 | 92av视频| 国产黄在线 | 亚洲精品日韩在线观看 | 欧美性猛片 | 黄色小说在线观看视频 | 97夜夜澡人人爽人人免费 | 亚洲免费在线播放视频 | 欧美日韩视频在线观看一区二区 | 久九视频| 特级西西人体444是什么意思 | 成人99免费视频 | 欧美日韩精品在线免费观看 | 久久久高清免费视频 | 日韩av手机在线看 | 日日日干 | www.com黄色 | 91精品在线观看入口 | 国产精品美女久久久久久网站 | 91成人亚洲 | 在线综合色 | 国产最新在线 | 伊人色**天天综合婷婷 | 国产精品不卡一区 | 黄色综合| 丝袜+亚洲+另类+欧美+变态 | 久免费 | 91麻豆产精品久久久久久 | 五月婷婷六月丁香在线观看 | 最近免费观看的电影完整版 | www天天干 | 国产婷婷在线观看 | 日韩三级视频 | 午夜久草 | 美国av大片 | 精品国产福利在线 | 久久久久久久久久久成人 | 6080yy午夜一二三区久久 | 九九在线高清精品视频 | 在线激情影院一区 | 91日韩免费 | 99免费在线 | 亚洲 欧美 综合 在线 精品 | 国产成人精品一区二区三区福利 | 人人插人人看 | 婷婷综合久久 | 亚洲无人区小视频 | 嫩嫩影院理论片 | 九七视频在线观看 | 国内精品久久久久久久久久清纯 | 亚洲撸撸 | 免费欧美高清视频 | 99免费在线观看视频 | 中文字幕频道 | 四虎成人精品永久免费av | av+在线播放在线播放 | 国产精品免费观看久久 | 狠狠干我 | 国产一区二区精 | 婷婷在线资源 | 色婷婷国产精品一区在线观看 | 欧美在线观看视频一区二区 | 国产一区视频免费在线观看 | 99色在线播放 | 国产精品久久久视频 | 午夜精品一区二区三区免费视频 | 在线观看国产福利片 | 成人午夜电影久久影院 | 日本激情动作片免费看 | 免费福利视频网站 | 免费电影播放 | 1024手机看片国产 | 欧美日韩精品在线观看视频 | 免费97视频 | 亚洲精品777| 日韩免费不卡视频 | 国产69精品久久app免费版 | 日日干激情五月 | 久久免费电影网 | 一本一本久久a久久精品综合小说 | 天天撸夜夜操 | 私人av| 人人爽人人爽人人爽学生一级 | 免费污片 | 91最新网址 | 日韩激情一二三区 | 精精国产xxxx视频在线播放 | 久久97久久 | 三级免费黄 | 中文av免费 | 国产伦精品一区二区三区高清 | 天天综合久久综合 | 亚洲三级网站 | 欧美黄网站 | 亚洲精欧美一区二区精品 | 国产中文欧美日韩在线 | 精品a视频| 一级性视频 | 国产精品99久久久久久有的能看 | 婷婷狠狠操 | 中文字幕在线观看1 | 日韩理论电影网 | 免费高清在线视频一区· | www国产一区| 亚洲美女视频网 | 丁香婷婷射| 亚洲欧美视频一区二区三区 | 天天干亚洲 | 国产成人免费精品 | 亚洲日本精品 | 99久久婷婷国产一区二区三区 | 波多野结衣一区三区 | 一级一级一片免费 | 国产中文字幕在线观看 | 天天天色综合 | 色噜噜日韩精品欧美一区二区 | 日韩精品专区在线影院重磅 | 国产一区二区三区免费在线观看 | 国产精品免费观看视频 | 精品福利网站 | 狠狠色伊人亚洲综合网站野外 | 91亚洲国产成人久久精品网站 | 日韩免费一区二区在线观看 | 国产欧美综合视频 | 欧美大片mv免费 | 亚洲午夜久久久久久久久 | 在线视频 一区二区 | 成人羞羞视频在线观看免费 | 亚洲蜜桃av | 精品亚洲男同gayvideo网站 | 久久国产色 | 97碰在线 | 91香蕉国产在线观看软件 | 久久高清精品 | 国产精品中文字幕在线 | 久久婷婷国产 | 亚洲精品小视频 | 国产精品久久久久久久久婷婷 | 五月婷婷国产 | 国产性xxxx | 色网站免费在线观看 | 亚洲欧美少妇 | 国产成人777777| 国产精品欧美久久 | 天天干天天操av | 中文在线免费视频 | www色,com| 欧美日韩在线免费观看 | 色偷偷88欧美精品久久久 | 黄色小说在线观看视频 | 亚洲日本在线视频观看 | 亚洲精品视频免费在线观看 | 婷婷射五月 | 在线你懂的视频 | 性色av香蕉一区二区 | 午夜10000 | 狠狠操精品 | 国产在线高清精品 | 午夜美女网站 | 午夜的福利 | 日本aa在线 | 五月婷丁香网 | 少妇视频一区 | 国产精品一区二区你懂的 | 西西444www | 国产福利一区二区在线 | 欧美精品免费在线 | 伊人激情综合 | 在线看片中文字幕 | 欧美激情综合五月色丁香 | 国产视频一 | 国产一级二级三级视频 | 婷婷九月激情 | 亚洲午夜久久久久 | 最近免费中文字幕大全高清10 | 久久精品99国产精品酒店日本 | 色噜噜日韩精品一区二区三区视频 | 国产女人40精品一区毛片视频 | 亚洲精品在线观看av | 色老板在线视频 | 亚洲国产视频在线 | 人人爽人人澡人人添人人人人 | 亚洲精品视频一二三 | 91在线免费观看网站 | 日韩精品一区二区三区中文字幕 | 精品久久久久久亚洲综合网站 | 日韩在线视频在线观看 | 免费日韩 精品中文字幕视频在线 | 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | 91爱在线 | 国产亚洲人成网站在线观看 | 成人在线播放网站 | 成人在线播放免费观看 | 麻豆视频在线播放 | 日本夜夜草视频网站 | 在线看91| www.国产在线观看 | 波多野结衣在线观看一区二区三区 | 国产成人精品一区二区三区免费 | 色婷婷激情四射 | 96久久| 久久精品中文字幕 | 91色欧美 | 国产精品一二三 | 久草久热 | 狠狠色丁香九九婷婷综合五月 | 中文字幕在线免费看线人 | 成人在线一区二区三区 | 久日精品 | 免费成人在线网站 | 久久99九九99精品 | 日韩黄色免费看 | 女人高潮特级毛片 | 国产精品久久久久免费a∨ 欧美一级性生活片 | 91九色丨porny丨丰满6 | 久久久久久久久福利 | 久草视频在| 99久久婷婷国产精品综合 | 国产破处在线播放 | 亚洲极色 | 中文字幕欧美三区 | 97色婷婷| 人人藻人人澡人人爽 | 日韩激情网| 极品美女被弄高潮视频网站 | 精品网站999www| 在线91网 | 日韩电影在线观看一区二区 | 久草在线视频精品 | 少妇av网 | 日本久久久久久久久久久 | 四虎www| 久久久久久久久影院 | 在线看国产视频 | 99精品视频播放 | 免费精品在线 | 超碰人人av | 免费视频你懂的 | 久久艹影院 | 91在线日本| 视频直播国产精品 | 97成人免费| 国产96av | 国产 欧美 在线 | 亚洲成人一区 | www.激情五月.com | 国产精品夜夜夜一区二区三区尤 | 操久久免费视频 | 国产精品电影一区二区 | 在线视频a | 国产精品九九久久99视频 | 日韩美女久久 | 我要色综合天天 | 天堂网av在线 | 97电影手机 | 天天色天天骑天天射 | 国产高清在线观看av | 久久视奸| 欧美精品久久久久久 | 日韩电影黄色 | 国产精品99久久久精品 | 国产成人精品女人久久久 | 久久久国产一区二区三区 | 91av美女| 综合av在线 | 探花视频在线观看免费版 | 亚洲综合在线播放 | 不卡av电影在线 | 久久9999久久免费精品国产 | 97在线免费 | 天天激情在线 | 日韩在线视频一区 | 狠狠干婷婷 | 亚洲精品久久在线 | 欧美黄色软件 | 经典三级一区 | 亚洲一区二区精品视频 | 国产自产高清不卡 | 综合久久一本 | 欧美日韩三区二区 | 在线观看av黄色 | 91看片网址 | 色综合久久88色综合天天 | 久久国产精品一区二区 | 成人高清av在线 | 国产亚洲精品福利 | 国产精品日韩欧美一区二区 | 国产自产在线视频 | 在线视频你懂得 | 97视频免费在线看 | 亚洲最大成人网4388xx | 国内精品久久久久影院男同志 | 在线看国产 | 丁香六月伊人 | 看国产黄色大片 | 亚洲五月六月 | 91九色porny蝌蚪主页 | 久久久国产精品成人免费 | 免费成人av| 欧美国产精品久久久久久免费 | 国产三级精品三级在线观看 | 亚洲精品456在线播放 | 综合色婷婷 | 欧美精品乱码久久久久 | 天天操天天吃 | 黄色av网站在线免费观看 | 日韩在线视 | 国产精品国产亚洲精品看不卡 | 国产精品v欧美精品v日韩 | 欧美91片 | 日韩av一区二区三区在线观看 | 欧美另类调教 | 成人资源在线播放 | 高清不卡一区二区三区 | 免费日韩三级 | 欧美大片mv免费 | 亚洲免费公开视频 | 久久成人精品电影 | 欧美一区二区日韩一区二区 | 99re亚洲国产精品 | 特黄色大片 | 午夜三级大片 | 亚洲在线精品视频 | 久久久国产精品人人片99精片欧美一 | 人人dvd| 国产中文字幕在线观看 | 欧美性视频网站 | 91成年视频 | 久久不卡国产精品一区二区 | 99精品在线 | 日韩欧美国产激情在线播放 | 国产做a爱一级久久 | 天天综合亚洲 | 日韩久久午夜一级啪啪 | 亚洲精品乱码久久久久久蜜桃91 | 久久躁日日躁aaaaxxxx | 久久免费在线观看视频 | 婷色| 天天干夜夜想 | 97综合网| 精品国产伦一区二区三区观看体验 | 久久精品网站免费观看 | 久久精品国产免费看久久精品 | 四虎永久免费 | 99久久精品免费看国产四区 | 99精品久久只有精品 | 91精品国产九九九久久久亚洲 | 成人黄色电影在线 | 国产成人一区二区三区免费看 | 欧美最新另类人妖 | 天天综合操| 免费视频97 | 免费av网址大全 | 久久国产精品99久久久久久进口 | 午夜资源站| 91在线免费视频 | 精品视频不卡 | 91插插插免费视频 | 日韩av一卡二卡三卡 | 99视频精品 | 国产一区自拍视频 | 91超国产| 久久精品久久久久 | 毛片网站在线看 | 久久综合色天天久久综合图片 | 五月天婷婷视频 | 婷婷综合影院 | av高清影院 | 91精彩在线视频 | 欧美 日韩 性 | 成人观看视频 | 成人免费毛片aaaaaa片 | 日本超碰在线 | av黄色免费看 | av在线一级 | 香蕉视频在线播放 | 九色自拍视频 | 色吊丝在线永久观看最新版本 | 精品欧美一区二区精品久久 | 黄色电影在线免费观看 | 亚洲无吗天堂 | 综合色在线观看 | 91精品国产乱码在线观看 | 日韩在线观看三区 | 国产精久久久久久妇女av | 免费男女羞羞的视频网站中文字幕 | 一级成人免费视频 | av中文电影| 久久爱综合| 久久久精品 一区二区三区 国产99视频在线观看 | 国产成人三级一区二区在线观看一 | 成人av电影在线 | 欧美国产高清 | 六月激情 | 不卡的av片 | 天天色天天射天天操 | 99久热在线精品视频 | 九九色网 | 午夜精品一区二区三区在线 | 精品久久久久久久久久 | 国产大陆亚洲精品国产 | 婷婷av资源| 免费亚洲电影 | 黄色美女免费网站 | 激情五月开心 | 又湿又紧又大又爽a视频国产 | 日本精品视频免费 | 波多野结衣小视频 | 性色xxxxhd| 国产精品综合在线观看 | 久久久wwww | 波多野结衣精品在线 | 中文字幕的 | 国产群p视频 | 日日爽天天 | 欧美巨大 | 婷婷国产v亚洲v欧美久久 | 久草在线免费资源站 | 99久久久久久久 | 月丁香婷婷 | 午夜视频免费在线观看 | 97超视频免费观看 | 亚洲国产高清在线 | 久久99精品国产99久久6尤 | av解说在线观看 | 在线视频一二三 | 91在线一区 | 久久av中文字幕片 | 999在线精品 | 91在线视频免费观看 | 免费在线观看成年人视频 | 色91在线视频 | 久久精品最新 | 国产精品成人一区二区三区吃奶 | 色激情五月 | 日韩a欧美 | 色99在线| 在线 精品 国产 | 免费网站看av片 | 亚洲精品麻豆视频 | 欧美91精品久久久久国产性生爱 | 亚洲高清在线精品 | 婷婷丁香色 | 天天干夜夜夜 | 成人av免费在线看 | 精品国产欧美一区二区三区不卡 | 成人app在线免费观看 | 日韩视频一区二区三区 | 操操色 | 国产美女精品视频免费观看 | 18做爰免费视频网站 | 中文字幕在线一区二区三区 | 91在线视频网址 | 色视频 在线 | 色婷五月天 | 一区二区三区高清在线观看 | 免费99精品国产自在在线 | 精品国产乱码久久久久久久 | 国产精品久久久久久久久久久免费 | 操久久网 | 欧美人体xx | 五月天视频网站 | 国产精品久久久久aaaa | 三级a毛片 | 中文字幕免费高清av | 日韩性xxxx | 91视频首页 | 人人爱人人射 | 91视频麻豆| 在线观看不卡视频 | 国产日韩欧美中文 | 欧美性成人 | 91三级视频 | 国产高清一 | 91在线在线观看 | 麻豆久久久久 | 精品欧美在线视频 | 制服丝袜在线91 | 欧美一级日韩三级 | 国产一区二区三精品久久久无广告 | 伊人手机在线 | www.亚洲激情.com| av资源在线看 | 日韩欧美精品一区二区三区经典 | 特级a老妇做爰全过程 | 国产精品 999 | 国产亚洲精品久久久久久大师 | 黄色免费网站下载 | 中文字幕精品一区 | 91桃色在线免费观看 | 天天干夜夜夜操天 | 九九在线高清精品视频 | 99热国产在线观看 | 在线视频免费观看 | 色婷婷久久久 | 免费国产在线观看 | 欧美性生交大片免网 | 日韩精品黄 | 国产精品久久亚洲 | 日韩精品一区二区三区电影 | 婷婷av电影 | 五月天婷婷在线视频 | 国产69精品久久久久9999apgf | 欧美一级欧美一级 | 亚洲午夜久久久综合37日本 | 亚洲精欧美一区二区精品 | 日日夜夜av | 中文字幕在线免费播放 | 高清不卡毛片 | 日本中文字幕网站 | 日本深夜福利视频 | 国产淫片 | www久 | 国产一区二区三区免费在线观看 | 中文字幕日韩av | 午夜精品久久久99热福利 | 国产精品久久99综合免费观看尤物 | 成人h在线| 中文字幕亚洲高清 | 在线观看视频亚洲 | 国产精品视频免费看 | 又黄又刺激视频 | 日韩视频欧美视频 | 国外av在线 | 91精品国产综合久久福利不卡 | 日韩大片免费在线观看 | 91热在线| 亚洲精品电影在线 | av大全在线看| 人人爽人人爽人人爽学生一级 | 丁香久久婷婷 | 色www.| 美女视频黄频 | 黄色精品国产 | 美女视频黄免费的久久 | 色综合中文字幕 | 日韩欧美一区二区三区在线 | 欧美日韩亚洲第一页 | 麻豆传媒电影在线观看 | 国产一区二区三区高清播放 | 午夜精品视频免费在线观看 | 黄色免费在线视频 | 国产亚洲精品成人 | 国产精品久久久av | 久久久麻豆视频 | 黄色一级大片在线免费看产 | 久久 精品一区 | 五月天综合色 | 天天干天天操天天操 | 狠狠色婷婷丁香六月 | av电影一区 | 精品国自产在线观看 | www黄色软件 | 91精品一区二区三区蜜桃 | 免费看黄色毛片 | 亚洲精品国产精品国自产观看 | 亚洲成人动漫在线观看 | 97色免费视频| 91视频91蝌蚪| 久草资源在线观看 | 国产精品va在线观看入 | 免费在线中文字幕 | 最近最新mv字幕免费观看 | 偷拍精品一区二区三区 | 中文字幕在线观看完整版电影 | 丁香六月国产 | 午夜电影久久 | 日韩网站免费观看 | 手机看片国产日韩 | 91大神dom调教在线观看 | 久久综合之合合综合久久 | av成人动漫 | 久久草av| 亚州黄色一级 | 在线观看视频三级 | 国产不卡视频在线播放 | 激情片av| 国产精品二区在线 | 日韩精品一区二区三区视频播放 | 久草在线资源观看 | 欧美福利视频一区 | 国产亚洲情侣一区二区无 | 国产小视频免费在线观看 | 精品久久中文 | 日韩免费中文 | 特片网久久 | 日韩在线二区 | 男女精品久久 | 国产精品精品久久久久久 | 成人在线视频在线观看 | 九色91福利 | www.久久久精品 | 999视频在线播放 | 天天干夜夜夜操天 | 九月婷婷人人澡人人添人人爽 | 亚洲综合色丁香婷婷六月图片 | 99在线免费视频观看 | 欧美精品一级视频 | 国产精品一区二区你懂的 | 成人亚洲综合 | 色婷婷中文 | 一级淫片a | 91少妇精拍在线播放 | 久久久久久国产精品亚洲78 | 国产网站色 | 久久99久久99精品免费看小说 | 成人午夜精品 | 99夜色| 欧美在线观看视频免费 | 国产91精品一区二区麻豆亚洲 | 国产乱对白刺激视频在线观看女王 | 成人免费视频网站 | 午夜国产一区二区三区四区 | 欧美日韩精品在线一区二区 | 国产精品久久久久久久久免费看 | 91黄视频在线观看 | 国产又粗又硬又长又爽的视频 | 视频在线一区 | 在线视频日韩精品 |