文章目录

  • 1. APK文件结构
  • 2. APK瘦身优化
    • 2.1 优化dex文件大小
      • 2.1.1 Proguard
      • 2.1.2 AndResGuard
    • 2.2 优化资源文件大小
      • 2.2.1 Android Lint
      • 2.2.2 tinypng
      • 2.2.3 WebP
    • 2.3 优化libs目录大小
      • 2.3.1 裁剪libs目录
      • 2.3.2 插件化

 APK,全称Android Application Package,即Android应用程序包,是Android系统使用的一种应用程序包文件格式,它的作用是将Android程序资源整合在一起,以便Android程序能在Android设备上正常运行。简单地说,就是一个Android应用程序的代码要想在Android设备上运行,必须先进行编译,然后被打包成一个被Android系统所能识别的文件才可以被运行,而这种能被Android系统识别并运行的文件格式就是"APK",而文件后缀为".apk"。

1. APK文件结构

 APK文件本质上是一个压缩文件,我们将一个APK文件进行解压,它主要包含以下文件:

  • assets目录:存放原生的静态资源文件,如图片、JSON配置文件、二进制数据、HTML5等。系统在编译时不会编译该目录下的资源,因此不会像res目录样能被直接通过R.xxx.xxx进行访问,而是需要通过AssetManager以二进制流的形式来读取资源。注意:res/raw目录存储的也是原生的资源文件,但是它能够被Android映射成R.xxx.xxx资源,它们的不同之处在于assets目录下的文件结构支持树形结构目录,而res/raw不支持。另外,assets目录下的单个文件尽量在1MB以下,而res/raw目录下的单个文件可以任意MB。
// 访问assets目录下的资源
AssetManager manager = this.getAssets();
InputStream in = manager.open("image/logo.jpg");//注意路径
Bitmap bitmap = BitmapFactory.decodeStream(in);// 访问res/raw目录下的资源
InputStream is = this.getResources().openRawResource(R.raw.logo);
Bitmap image = BitmapFactory.decodeStream(is);
  • lib目录:存放应用程序依赖的不同架构(ABI)的.so文件。
  • res目录:存放应用的资源文件,包括图片、字符串、颜色、尺寸、动画文件、布局文件等资源。这个目录下的所有资源都会出现在资源清单文件R.java的索引中。
  • MERA-INF目录:保存应用程序的签名信息,签名信息可以验证APK文件的完整性。
    • MANIFEST.MF:该文件保存了APK包中每个文件得名字及其SHA1哈希值;
    • CERT.SF:该文件保存了MANIFEST.MF文件的哈希值及其文件中每一个哈希项的哈希值;
    • CERT.RSA:该文件保存了APK包的签名和证书的公钥信息;
  • AndroidManifest.xml:Android 应用的配置文件,用于描述 Android 应用的整体情况。每个 Android 应用必须包含一个 AndroidManifest.xml 文件。AndroidManifest.xml 包含了 Android 四大组件的注册信息,权限声明以及 Android SDK 版本信息等,该文件将会被编译成二进制文件。
  • classes.dex:应用程序可执行文件,即Dalvik字节码文件。APK中可能包含多个dex文件,具体要看Android程序的所有方法数是否超过65535,如果超过就进行分包处理,就会出现多个dex文件的情况。
  • Resources.arsc:资源配置文件。该文件用于记录资源文件位置和资源ID之间的映射关系,以便系统能够根据ID去寻找对应的资源路径。该ID实际上与R.java中存储的是一样的,但是R.java只是便于开发者调用资源且保证编译程序不报错,而实际上在程序运行时系统需要根据这个ID从Resources.arsc文件保存的对应的路径中获取资源文件。

2. APK瘦身优化

 在第1小节中,我们介绍了一个APK文件的结构主要由动态库目录(lib)、资源文件目录(assets&res)、字节码文件(.dex)、资源配置文件(Resources.arsc)以及清单文件(AndroidManifest.xml)等组成,其中,lib目录assets&res目录、.dex文件这三部分对整个APK文件大小占比达到99%以上,这里可以通过AS的可以看出。也就是说,对于APK文件的瘦身优化,将从字节码文件、资源文件以及动态库这三个方面入手。AS执行"Build->Analyze APK"操作效果图如下:

2.1 优化dex文件大小

2.1.1 Proguard

 ProGuard是Android SDK中提供的一个可用于对Java字节码文件进行压缩优化混淆以及预校验的免费工具,它通过工程中所有代码以找出无用的代码并将其移除,同时还会使用语义上隐晦的名称来重命名代码中的类、接口、字段和函数等,达到压缩、优化和混淆代码的功能,从而使最终生成的APK文件变得更小、效率更高、更难被反编译。在工程中开启混淆方法,修改app module的build.gradle文件。

android {...buildTypes {release {// 开启Proguard打包混淆minifyEnabled true// 指定混淆规则文件// 自定义规则在proguard-rules.pro文件proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}
  • ProGuard工作原理

ProGuard具体工作流程如下:

  1. 压缩(Shrink):检测并移除代码中无用的类、字段、方法和特性;
  2. 优化(Optimize):分析和优化相关方法字节码,移除无用的指令;
  3. 混淆(Obfuscate):使用随机的小写且无意义的名称对类、字段和方法进行重命名;
  4. 预校验(Preverify):在Java平台上对处理后的代码进行预校验,确保加载的class文件是可执行的。
  • Proguard使用参数
参数 作用
-optimizationpasses 指定混淆压缩比,0~7之间,默认-optimizationpasses 5
-dontusemixedcaseclassnames 混淆时不使用大小写混合,混淆后的类名为小写
-dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类
-dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员
-dontpreverify 不做预校验,安卓不需要preverify,去掉这一步可加快混淆速度
-verbose 混淆后就会生成映射文件,包含有类名->混淆后类名的映射关系等
-dontoptimize 优化,不优化输入的类文件
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员
-printmapping 指定映射文件的名称,如-printmapping proguardMapping.txt
-dontshrink 压缩,不压缩输入的类文件
-optimizations 指定混淆时采用的算法,后面的参数是一个过滤器-optimizations !code/simplification/arithmetic,!field/,!class/merging/
-keepattributes [attribute_filter] 不混淆相关属性,比如:(1) -keepattributes Annotation不混淆代码中的注释(在JSON实体映射中非常重要);(2) -keepattributes Signature,不混淆泛型;(3) -keepattributes SourceFile,LineNumberTable抛出异常保留代码行号
-keep [,modifier,…] class_specification 不混淆指定的类文件和类的成员(变量、方法),比如:(1) -keep public class * extends android.app.Activity不混淆所有Activity的子类(2) -keep public class com.xxxx.app.ui.fragment.** {*;}不混淆android-support-v4.jar包下的所有类及类的成员
-keepclassmembers[,modifier,…] class_specification 不混淆指定类的成员,比如:(1) -keepclassmembers class * extends android.app.Activity {public void *(android.view.View);}不混淆所有Activity的子类中参数是view的方法;(2) -keepclassmembers enum * {public static [] values();public static valueOf(java.lang.String);}不混淆所有枚举类
-keepclasseswithmembers [,modifier,…] class_specification 不混淆指定的类和类的成员,但条件是所有指定的类和类成员必须存在,如保留所有的本地native方法不被混淆:-keepclasseswithmembernames class * { native ;}
-keepnames class_specification 不混淆指定的类和类的成员的名称
-keepclassmembernames 不混淆类的成员名
-keepclasseswithmembernames 不混淆类的及其成员名
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件
-libraryjars class_path 声明引入的第三方库,比如支付宝SDK:-libraryjars libs/alipaysdk.jar
-dontwarn 不提示引入第三方库发出的警告-dontwarn com.alipay.android.app.**
文件过滤(File Filters) (1) ?(问号):匹配文件名中的一个字符(2) *(单星号):匹配任何一个文件名,但不包含目录分隔符(3) **(双信号):匹配任何一个文件名,及任意数量的目录分隔符(4)!(感叹号):匹配除!之外的内容举例:java/*.class,匹配java目录下的所有java文件,不包子目录java/.class,匹配所有Java文件,包括子目录下的java文件!.gif,images/,匹配images目录下所有除gif格式文件

注:关于Proguard的具体使用,请参照我这篇文章。

2.1.2 AndResGuard

 AndResGuard是微信团队开源的一个缩小APK大小的工具,它的原理类似于Proguard,但是只针对资源,它会把原本冗长的资源路径变短,比如讲res/drawable/wechat变为r/d/a。相比于Proguard,AndResGuard的优势在于它通过自己实现安装包解压和利用7z极限压缩进行打包,使得整个混淆打包过程不依赖源码和编译流程,只需输入一个APK文件(无论签名与否、debug版、release版),从而做到最大混淆,大大减少了安装包体积,同时也提升了APk被破解的难度。AS中配置方法如下:

  • 配置根目录下的build.gradle文件
buildscript {repositories {jcenter()google()}dependencies {classpath 'com.android.tools.build:gradle:3.1.4'// 添加依赖,AndResProguardclasspath 'com.tencent.mm:AndResGuard-gradle-plugin:1.2.17'}
}
  • 配置app目录下的build.gradle文件
apply plugin: 'AndResGuard'android {...
}dependencies {...
}andResGuard {// mappingFile用于keep住资源原有的物理路径// mappingFile = file("./resource_mapping.txt")mappingFile = nulluse7zip = trueuseSign = true// 打开这个开关,会keep住所有资源的原始路径,只混淆资源的名字keepRoot = false// 设置这个值,会把arsc name列混淆成相同的名字,减少string常量池的大小fixedResName = "arg"// 打开这个开关会合并所有哈希值相同的资源,但请不要过度依赖这个功能去除去冗余资源mergeDuplicatedRes = true// 设置白名单,即不混淆某些资源// 白名单机制只作用于资源的specsName,不会keep住资源的路径// 如果想keep住资源原有的物理路径,可以使用mappingFilewhiteList = [// for your icon"R.drawable.icon",// for fabric"R.string.com.crashlytics.*",// for google-services"R.string.google_app_id","R.string.gcm_defaultSenderId","R.string.default_web_client_id","R.string.ga_trackingId","R.string.firebase_database_url","R.string.google_api_key","R.string.google_crash_reporting_api_key"]// 指定压缩的文件类型。支持以下三种文件通配符:// * 为文件通配符,表示0个或多个字符;// ? 表示0个或1个字符;// + 表示1个或多个字符;compressFilePattern = ["*.png","*.jpg","*.jpeg","*.gif",]// 配置7Zip// 只需设置artifact或path,如果同时设置总以path的值为优先// 注意:对于发布与Google Play的APP建议不要使用7Zip压缩sevenzip {artifact = 'com.tencent.mm:SevenZip:1.2.17'//path = "/usr/local/bin/7za"}/*** 可选: 如果不设置则会默认覆盖assemble[BuildType | Flavor]输出的apk* 如果配置则输出至finalApkBackupPath配置路径**/// finalApkBackupPath = "${project.rootDir}/final.apk"/*** 可选: 指定v1签名时生成jar文件的摘要算法* 默认值为“SHA-1”**/// digestalg = "SHA-256"
}

 接着,Sync Android项目,同步完毕后我们打开Android Studio右侧栏的Gradle选项,展开:app就会出现一个名为"andreguard"的目录,该目录包含了一些可执行选项,用于执行混淆打包。

 这里我们双击resguardRelease执行生成被打包混淆APk,保存路径位于目录app/build/ouputs/realse中,会自动生成一个AndResGuard_app目录,然后目录下面有多个被混淆打包的apk文件,而app-rlease-signed-7zip-aligned.apk就是我们需要的release版apk。通过apktool工具进行反编译,发现确实已经将所有资源(非白名单)进行了混淆,且APK的大小由在没有做任何资源优化的情况下由原来的20MB减小到16MB,可以说明效果还是很明显的。生成APk路径如下:

 当然,除了直接在AS中配置AndResGuard,我们也可以官方提供的andresguard.jar来对apk文件进行混淆,该方式简单用法如下所示:

// 直接混淆处理,默认配置和输出路径
java -jar andresguard.jar input.apk// 若想指定配置文件或输出目录
java -jar andresguard.jar input.apk -config yourconfig.xml -out output_directory// 若想指定签名信息或mapping信息:
java -jar andresguard.jar input.apk -config yourconfig.xml-out output_directory -signature signature_file_path storepass_valuekeypass_value storealias_value -mapping mapping_file_path// 若想指定7zip或zipalign的路径(若已设置环境变量,这两项不需要单独设置):
java -jar andresguard.jar input.apk-7zip /shwenzhang/tool/7za  -zipalign /shwenzhang/sdk/tools/zipalign// 若想用7zip重打包安装包,同时也可指定output路径
// 指定7zip或zipalign的路径(此模式其他参数都不支持):
java -jar andresguard.jar -repackage input.apk -out output_directory-7zip /shwenzhang/tool/7za  -zipalign /shwenzhang/sdk/tools/zipalign

除此之外,还可以从以下几个方面进行优化:

  • 删除无用或重复的第三方库、jar包;
  • 重新编译第三方库。由于很多时候在项目中,对于第三方库只使用了部分功能,我们可以尝试抽取出项目用到的部分并重新编译,以此来减小dex文件大小。但是,重新编译第三方库可能会引起较多的问题,不到万不得已,尽量不要走到这步。

2.2 优化资源文件大小

2.2.1 Android Lint

 Android Lint是Android SDK于ADT16引入的一个非常强大的代码扫描工具,它通过对Android工程源码代码进行扫描和检查,来帮助开发者自动检测代码的质量、安全问题以及无用资源,通俗来说就是发现潜在的错误,便于开发者及早修正这些问题。Android Lint工作过程比较简单,整个Lint过程由Lint Tool(检测工具)Source Files(项目源文件)lint.xml(配置文件) 三个部分组成,Lint Tool 读取 Source Files,根据 lint.xml 配置的规则输出结果。Lint工作原理大体如下:

  • 启动Lint

  由于Android Studio直接集成了Lint,因此我们无需再安装Lint工具,只需点击主菜单->Analyze-> Inspect Code即可启动Lint工具。弹出检查配置对话框如下:

 其中,注释1选项卡用于设置检查的范围,默认为整个工程(whole project),我们也可以选中Custom scope指定感兴趣的范围,比如某个module;注释2用于指定检查配置文件,这里选中默认就好(Project Default)。然后,点击面板上的OK按钮,等待几分钟就可以看到检查结果,如下图所示:

 从结果面板可知,Lint结果由4部分组成:注释1为Lint检查结果,可以根据不同方式对检查结果进行展示,比如按照问题的严重程度分组、按照目录分组等;注释2给出自动修改方案,我们点击对应的按钮AS便可完成修改;注释3给出的是对问题的描述;注释4用于在指定区域检查同类问题。

  • 根据规则名称来检查

 在APK瘦身优化中,我们用得较多的就是使用Android Lint移除工程中那些无用的资源,可以通过点击主菜单->Analyze -> Run Inspection By Name实现。弹出对话框后,在过滤框中输入unused resources关键字,双击下拉列表中的unused resources选项,然后会弹出检查范围设置对话框,这里我们使用默认Project Default,点击OK后,等会儿就会出现检查结果。检查结果如下:

 需要注意的是,Lint工具无法检查出被反射访问的资源,如果有反射访问情况,请复查下以免错删。另外,Lint分析资源文件时会跳过assets文件,对于该目录下的资源需要自行判断是否有使用,如果没有,尽量将其从工程中删除。

2.2.2 tinypng

 Tinypng 是一款 PNG 图片压缩工具,压缩率能达到 50% 以上,图片在压缩之前和之后几乎看不出差别,几乎是无损压缩。Tinypng API 支持所有主流的平台,除了图片压缩,Tinypng 还支持对图片做缩放,裁切等处。据官网介绍,它的原理是通过合并图片中相似的颜色,通过将 24 位的 PNG 图片压缩成小得多的 8 位色值的图片,并且去掉了图片中不必要的 metadata(元数据,从 Photoshop 等工具中导出的图片都会带有此类信息),这种方式几乎能完美支持原图片的透明度。它还有一个兄弟叫 Tinyjpg,支持 JPG 图片压缩。

  • tinypng使用方法

 tinypng工具使用非常简单,即打开官网,然后将png格式图片拖拽到主页上方的方框区域即可。

  • 压缩效果。

    可以看出,几乎没有什么区别。

2.2.3 WebP

 WebP是谷歌于2010年发布的一种旨在加快图片加载速度的图片格式,派生自图像编码格式VP8 。它不仅支持无损或有损压缩、alpha通道,还支持动画演示。在同画质的情况下,webp格式图片占用体积相较于jpg图片大约减少40%,相较于无损png图片大约减少30%。目前移动端Android4.0(API 14,如果需要支持无损和透明通道API>=18)以上、PC端chorme 10+(14 ~ 16 有渲染bug)、opera 11+ 、safri均支持webp格式图片。Android Studio 可以将 PNG、JPG、BMP 或静态 GIF 图片转换为 WebP 格式,支持转换单张图片,也可以转换包含多张图片的文件夹。要转换某张图片或包含多张图片的文件夹,请按照下列步骤操作:

  1. 右键点击某个图片文件或包含很多图片文件的文件夹,然后点击 Convert to WebP
  2. Converting Images to WebP 对话框随即打开。默认设置取决于当前模块的 minSdkVersion 设置。
  • 面板说明:

    • 注释1:使用有损压缩,Encoding quality用于设置压缩质量;
    • 注释2:使用无损压缩,需minSdkVersion>=18;
    • 注释3:转换后比原始图片大则舍弃,默认开启;
    • 注释4:不转换.9.png图片,默认开启;
    • 注释5:是否跳过包含透明(alpha)通道的图像,minSdkVersion<18默认跳过。
  1. 点击OK开始转换。如果您在上面选择了无损转换,系统会立即进行转换,并覆盖原来的生成一张后缀为.webp的图片;如果您选择了有损转换,并且选择在保存之前查看每张转换后图片的预览效果,其中,注释1处显示了原始图像和编码图像之间的像素,注释2处的进度条用于设置压缩转换质量,当设置为75%时,原始图和转换后图像基本看不出差异,但是图片的大小由749.7KB降到17.9KB,相比于tinypng压缩的158.8KB,整整比处理后的PNG图像又降了88%左右,相对于原始图像缩小了98%。有损压缩预览如下:

 除此之外,还可以从以下几个方面进行优化:

  • 尽量不要使用帧动画,因为一个帧动画会包含多张图片;
  • 将较大的资源文件放到服务端,APP启动后自动下载使用;
  • 针对所有屏幕密度,尽量使用一套图片资源、一套布局、多套dimens.xml文件,在使用最小资源的情况下实现多分辨率的适配;
  • 去除无用或功能上重复的第三方库,因为这些库也包含了自身的资源文件;
  • 对assets资源目录作一定取舍,因为该目录资源保存的是原始资源。
  • 使用gradle开启shrinkResources;
android {...buildTypes {release {// 移除无用的resource文件shrinkResources true// 开启Proguard打包混淆minifyEnabled true// 指定混淆规则文件// 自定义规则在proguard-rules.pro文件proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}
}

2.3 优化libs目录大小

2.3.1 裁剪libs目录

 为了支持不同的CPU指令集,在Android工程中的lib目录可能会包含多种不同的CPU架构的so文件,比如armeabiarmeabi-v7ax86mipsarm64-v8a等。它们的区别如表所示:

具体说明:

  • armeabi:第5代 ARM v5TE,使用软件浮点运算,兼容所有ARM设备,通用性强,速度慢;

  • armeabi-v7a:第7代 ARM v7,使用硬件浮点运算,具有高级扩展功能。兼容支持armeabi和armeabi-v7a,,是目前Android手机主流CPU;

  • arm64-v8a:第8代,64位,包含AArch32、AArch64两个执行状态对应32、64bit。兼容支持armeabi、armeabi-v7a和arm64-v8a;

  • X86:一般用于平板,兼容支持 armeabi(性能有所损耗) 和 x86;

  • x86_64:一般用于平板,兼容支持 x86 和 x86_64;

  • mips、mips64:基本用不上;

 从上面的分析可知,由于armeabi架构的Android设备基本被淘汰了,目前主流的CPU架构为armeabi-v7a,且该架构前后支持armeabiarm64-v8a设备,也就是说,除非特殊情况需要做CPU架构适配,一般情况我们在Android应用中保留armeabi-v7a架构就可以了。通过删除其他架构的so,实现减小APK的体积。

2.3.2 插件化

 使用插件化技术动态加载so文件,以达到减小APK包体积的目的。关于插件化技术,将在接下来的文章中讲解。

Android性能优化(5):APK瘦身优化相关推荐

  1. android app性能优化_Android性能优化之Apk 瘦身优化

    瘦身 主要是下载转换率提高 头部App都有Lite版本 渠道合作产商要求 APK 分析工具 ApkTool 反编译工具 官网:https://ibotpeaches.github.io/ApkTool ...

  2. Android性能优化之APK瘦身最全总结

    Android性能优化之APK瘦身最全总结 随着业务复杂度的逐渐增加,代码.资源也在不断的增加,此时你的APP大小也在增加.从用户层面来说,面对动辄几十兆的APP来说在非WIFI情况下还是会犹豫要不要 ...

  3. Android 性能优化(62)---存检测、卡顿优化、耗电优化、APK瘦身——详解篇

    Android 性能优化,内存检测.卡顿优化.耗电优化.APK瘦身--详解篇 自2008年智能时代开始,Android操作系统一路高歌,10年智能机发展之路,如今 Android 9.0 代号P  都 ...

  4. Android性能优化之APK瘦身详解(瘦身73%)

    image 公司项目在不断的改版迭代中,代码在不断的累加,终于apk包不负重负了,已经到了八十多M了.可能要换种方式表达,到目前为止没有正真的往外推过,一直在内部执行7天讨论需求,5天代码实现的阶段. ...

  5. App性能优化(布局优化,线程优化,app瘦身优化,页面切换优化,App启动优化,内存优化)

    Android APP性能优化(最新总结) 在目前Android开发中,UI布局可以说是每个App使用频率很高的,随着UI越来越多,布局的重复性.复杂度也随之增长,这样使得UI布局的优化,显得至关重要 ...

  6. Android开发——今日头条APK瘦身之路

    随着版本迭代,功能增加安装包体积也会慢慢增大. 今日头条576版本APK达到了25M,通过一系列的优化,到目前的607版本为12M.本文主要是介绍头条APK瘦身中用到的一些方法. APK分析 既然是要 ...

  7. Android性能优化(一)闪退治理、卡顿优化、耗电优化、APK瘦身

    系列推荐: Android 性能优化(二)Handler运行机制原理,源码分析 Android 性能优化(三)认识错误Error和异常Exception及栈轨迹StackTrace Android 性 ...

  8. 性能优化之Apk瘦身

    基本瘦身 1.工具(Lint检测代码) 箭头1:全面检测 检测维度: 大牛文章: https://www.cnblogs.com/andy-songwei/p/7090934.html http:// ...

  9. APK瘦身优化检测工具-Matrix ApkChecker 使用

    简介 Matrix-ApkChecker 作为Matrix系统的一部分,是针对android安装包的分析检测工具,根据一系列设定好的规则检测apk是否存在特定的问题,并输出较为详细的检测结果报告,用于 ...

最新文章

  1. 文巾解题 881. 救生艇
  2. numpy中的ndim、shape、dtype、astype
  3. 电影院票务管理系统数据库设计(1)
  4. SharePoint 使用脚本为表单绑定事件
  5. 所谓高情商就是会说话--总结
  6. Python中利用parse_args与namespace来简化函数传参
  7. go 协程和协程通信
  8. 深入讲解防火墙的概念原理与实现
  9. jsp中提供的四种属性范围
  10. 锐起无盘换服务器怎么备份数据,请问锐起无盘高手~!如何替换中毒的系统(锐起无盘系统C盘)用备份镜像或上传系统?如何做详细点本人菜鸟...
  11. 网页|利用touch实现下拉刷新
  12. 简要分析VB6.0和VB.NET区别
  13. 双人五子棋游戏用C++实现
  14. 《快速掌握QML》第六章 动画
  15. MySQL插入emoji表情错误的3种解决方案,Incorrect string value: '\xF0\x9F\x98\x84'
  16. Matlab 图像几何变换
  17. 计算机数值方法之最小二乘法拟合多项式C语言
  18. NEW RDSP MODE I (快速幂)
  19. 《Java程序性能优化》
  20. Qiime2 软件安装

热门文章

  1. 郑豪8.31月K收官提防大洗盘,日K箱体先高空,黄金亚欧盘最新操作建议
  2. 用windows“记事本”创建一个文本文件(hamlet.txt),其中每行包含一段英文。试读出文件的全部内容,并判断:(1)该文本文件有多少行?(2)文件中以大写字母开头的有多少行?
  3. CCRC信息安全服务资质认证涨价了?最新规定已发布,重点已经给你们划好了~
  4. s 参数 快速 记忆法
  5. 笔记本电脑升级后无法用拓展坞供电,提示显示器连接可能受限。
  6. 基于python实现openai可结合上下文的问答,含html在线版
  7. 校盈家学校财务收费管理软件,最适合学校财务收费的管理工具!
  8. 如何在MAC中使用内网穿透
  9. 取余c语言输入一行中一个正整数n pta,正整数
  10. 2018 中国城市天气代码