V2EX - 技术 |
- 深入理解 android 包体积优化,给 apk 瘦身全部技巧
- 看到 Go 与 MongoDB 的交互方式,我想放弃 Go 了
- 我坦白,我是一个假程序员
- js 生成中文 PDF 有啥好办法?
- debian 系统下,有没有简单的办法检测指定网卡配置是 dhcp/static/manual?
- 一个小白想法, Python 为什么不通过命令行开关切换两种 GIL 模式?
- 是否有针对为了兼容的多余代码的代码检查?
- Windows 11 的那个任务栏角溢出有办法和以前一样全部显示吗?
- 请问如果要组建 100 个节点以上的集群,如何给机器配置免密登录呢?如果后期这个集群扩容到 200 个节点以上,该如何操作?有大佬提供下思路吗?
- 温州“遇见志同道合”线下沙龙 - 集合温州对互联网开发有热情的小伙伴
- Language Server for Java ™ 1.0 在 VS Code 上正式发布!
- Android 12 发布了,鸿蒙什么时候能 rebase 下主干
深入理解 android 包体积优化,给 apk 瘦身全部技巧 Posted: 24 Oct 2021 04:21 AM PDT 前言随着 iphone13p 最大内存放大到了 1T ,大内存手机的时代悄然降临,在 android 里面,三星也有,罗老师几年前说:如果我告诉你们我们在做 1T 的手机,你们可能以为我疯了。 看看现在,估计未来会有更多手机有 1T 版,大家开始真香了。 但是,如果现在有人说:要做一个 1T 大小的 app ,那他可能是真疯了,至少未来十年不可能。因为手机内存是越大越好,你一个 app 当然是能小就小呀 Android app 的文件格式为 apk ,本文就是探讨对于一个 android apk ,有哪些方法可以减小体积 Apk 组成要想减小体积,首先我们需要了解 apk 的构成
上面是抽象的 apk 结构,下面我们看一个实际的 将 qq.apk 拖入 android studio 可以看到最大的 R 文件夹,点进去,都是一些图片,第二大的是 assets ,里面是一些表情包以及插件图片 其他的我们刚刚也说过,值得注意的是,里面多了一个 META-INF 他存放了应用的签名信息,其中
这样子,一个 app 安装在手机时,解密这一数字摘要,然后与内部的.MF 文件比对,如果相符,证明资源内容没有被修改 Dex 文件在 APK 组成中我们可以看到,占用内存最大的是 res ,assets 与 classs.dex 文件,这也是我们的优化方向,接下来,我们看看如何优化 dex 首先我们看看 dex 的结构 更详细的版本在官网,这里如果对这些结构的作用有兴趣,可以看下图的详细版本 ProGuadrddex 是代码编译而来,而对于代码文件,最重要的优化就是混淆了,将方法名,属性名等变为又短又无意义的名字,不仅能缩小体积还能避免反编译被人破解 在 IDE 中,我们可以看到 qq 里面的类都是小写字母,里面的变量和方法都按字母顺序排列了,从 a 开始 除了修改变量名,ProGuadrd 还可以在功能等价的基础上重写代码,比如把多个函数调用写到一个函数里面去,更加增大了阅读理解难度(虽然初学者一般已经这样做了),以及打乱格式,增加空格等 主要步骤如下
D8 与 R8 优化这两平时接触不多,他们主要是在字节码处做优化的,开发时感知不强(感觉就是用来面试的) D8 主要是在编译字节码时重排序,将占用空间变得更小,比如对于 greetingType 方法,正常编译后的结果是 如果使用 D8 优化,编译后的结果 可以看到 0008 处后的几条指令有变化,多了几个 if ,对于不同的 case 做创建不同的变量,可以节省空间 R8 也类似,只是策略有些不一样 更详细的了解可以参考 D8 Optimizations 总之,他们的作用是就是,在不改变功能的情况下,重写部分 class 指令,减小空间占用,但是有可能会增加指令数量 Redex 优化Redex 是 Facebook 推出的一个优化 Dex 文件的工具,和 D8R8 一样,也是对字节码的处理,有以下效果
…… 不过这个我没用过,但是感觉 Proguard 与 D8R8 都多多少少能做到,可能是他在细节上用了更好的算法 但是不管多少框架,对 dex 文件的优化说来说去也就这些 移除多余的库与代码最后是移除第三方库和冗余代码,属于业务逻辑上的原因
资源清理上面都是在代码层面减小 dex ,apk 的另一个空间占用大户,是资源,尤其是其中的图片, 图片,你可知道,多少 OOM 因你而起?多少 app 因你闪退? 图片压缩与更换格式我们先看看图片为什么那么大 图片的显示,有 ARGB 4 个通道,其中默认的显示模式是 ARGB8888 ,ARGB8888 表示每个通道的颜色区间为[0,255],也就是两个 16 进制数表示,也就是 8bit -> 1 字节 所以 ARGB8888 模式下,一个像素 4 个通道下占用 4 字节,一张 1024*1024 的手机图片图片,就是 $$ 2^{10} * 2^{10} * 2^2 = 2^{22} = 4M $$ 一张图 4M ,太离谱了! 上面是打开后在运存的占用,我们可以修改颜色通道,不然 ARGB565 来减小单个像素所占用运存,不过有点跑题,本篇我们讲的是 app 的大小,也就是所占用手机的内存(我们约定 手机运存 = 电脑内存,手机内存 = 电脑硬盘) 内存与运存中的图片存在形式是不一样的,压缩方法也不一样,很多人容易弄混 回到内存,内存中,图片是以 png ,jpg 等格式存储 我之前开发的时候都是先将 png 图片,往 tinypng 网站中压缩一下再放入,所以可以压缩图片,一般能压个三分之一~三分之二。 也可以更换图片格式,比如 webp ,svg 可以更小,android studio 也提供了对应的支持,但是没有最好的格式,只是适用场景不同 这里多提一下 webp ,因为这是 google 推出的,大家在谷歌浏览器下载图片的时候,一般默认下载下来就是 webp 格式,所谓更小的内存占用,本质上是对图片进行了压缩,webp 的压缩算法是 VP8 视频编码,核心逻辑就是将图片分割成更小的子块,然后预测周围像素值,预测越准,周围的像素值就可以删去,再在图片打开时算出删掉的像素 图片网络化在微信或者 qq 聊天中,对方发来一张图片,我们在聊天窗口往往先看到一张很模糊的缩略图,当点击时才会加载出高清图, 这个思路也可以用在 apk 中,很多入口较深的高清大图,或者需要经常更新的图片,也许用户根本不看,就没有必要内置在 apk 中,看时加载即可,如果需要提前占位置,可以用缩略图代替 至于哪些图网络化,需要根据业务与用户体验来权衡了 比如淘宝,在断网情况下打开时,只有 icon 内置了 其他策略无论是对 Dex 还是对资源进行优化,虽然安全有效,但是本质上是将原来有的东西变得更小,对 apk 的瘦身程度是有限的,还有一些"七伤拳",优化率极高,但是对 apk 的影响也很大,需要谨慎使用。 插件化所谓插件化,就是将 apk 中的非主要功能弄成独立的 apk ,原主 apk 称为宿主。 比如支付宝里面,就是搞支付的,那么他里面的什么口碑,基金,天猫一堆乱七八糟,同时功能独立的东西就非常适合做成插件,用户用到的时候再从网络加载进来,这样极大的减少了 apk 占用。 但是这里涉及到比较多的技术问题:
一般来说,通过的是代理和反射来处理,腾讯有一个 shadow 框架可以大致实现"零反射",
不过插件化技术不在今天的讨论范围,有兴趣可以研究下tencent-shadow 当使用了插件化后,项目基本是要重构了,相比起改改 Dex 和图片,这个工程量极大,但是收益也会很高 webview这里类似于图片网络化,相对于图片,直接将整个界面都变成 url , 我们手机 app 中的小程序一般都是 url 显示在 webview 中 相关技术可以使用 jsBridge 与 Hybird ,本质上就是通过 bridge 连接 h5 与 android iOS ,实现通信 不过代价就是,加载速度慢于原生,还要注意防止网址篡改等 小结本文我们讨论的是 apk 的瘦身方案,首先先明确了 apk 的主要组成部分为 dex 文件与资源文件
除了这些常规操作,我们还可以使用插件化与 Webview 方法极致减少体积,但是这两个技术工程量大,而且有性能代价,需要谨慎使用。 参考资料 |
看到 Go 与 MongoDB 的交互方式,我想放弃 Go 了 Posted: 24 Oct 2021 04:20 AM PDT 之前习惯了 python/js 这种语法,感觉很自然很方便。 今天看了下 MongoDB 官方的 Go 接口,哎呀,那交互方式,真的是痛苦。 例如查询用户为 1 的用户:{userid: 1},在 Go 里面你还得包裹为 bson.D{{"userid", 1}} 返回的结果是一个索引,要 Decode 下,Docode 还需要传递一个结构体过去。 还得传递一个 context (还没看为啥要这么做,其他语言不用) 感觉一点也不方便,代码很多不美观不优雅,习惯了 js/python 这种比较简单直观的语法,难以接受呀。 感觉 Google 最近出的东西,语法都那么特立独行的,还有一个是死亡嵌套 Flutter ,嵌套到怀疑人生。 官方教程: https://www.mongodb.com/blog/post/mongodb-go-driver-tutorial |
Posted: 24 Oct 2021 03:54 AM PDT 今天 10 月 24 号,程序员节 非常荣幸能够在 V2EX 认识了不少程序员朋友,祝你们节日快乐 今天我不能为自己庆祝,因为我不是一个真正的程序员 作为一名真正程序员,github 账户是必备吧 虽然我也有 github 账户,但是我从来没有用过 git cli Github 和 codepen 是我的最爱,平时 fork 和 download 是我的日常 非科班出身,但是我自己也挺努力,自学了 PHP PYTHON GOLANG NODEJS VUE 我目前在做的网站主要是 miao.win 以及 dot.af ,欢迎各位莅临指导工作 |
Posted: 24 Oct 2021 02:00 AM PDT html2pdf 支持中文,html 排版,但是生成的 PDF 是图片的,无法复制里面的文字 jspdf 搞了好久无法支持中文,然后前端加载一个几十兆的字体也麻烦 |
debian 系统下,有没有简单的办法检测指定网卡配置是 dhcp/static/manual? Posted: 24 Oct 2021 01:14 AM PDT 我想到的是通过查找网卡配置文件 /etc/network/interfaces 的内容来判定,但是网卡配置可能写到了 /etc/network/interfaces.d 下的某个文件,而且配置文件内容的一行要是被拆成了奇形怪状的好几行怎么办?虽然多写几句 bash script 也能搞定,但是想问问有没有别的办法。 那个 ifquery 命令我试过,没有用,按 help 输出和 manpage 操作,要么输出为空,要么根本不能正常解析它自己的选项,连示例都不能运行。 |
一个小白想法, Python 为什么不通过命令行开关切换两种 GIL 模式? Posted: 23 Oct 2021 09:24 PM PDT 最近 python 出现一个惊艳的 no-gil 设计,想必大家已经知道了。 那么对于 python GIL 这个老问题,似乎常见的说法是: 粗粒度的 GIL 降低多线程的性能,细粒度的 GIL 降低单线程的性能。 那为什么不全都要,通过命令行开关切换两种 GIL 模式? 我本身并不太懂同步原语、线程安全、并行编程这些,所以想请教一下。欢迎指正! |
Posted: 23 Oct 2021 06:44 PM PDT Python 每个新版本中的标准库会新增一些更便捷的功能,但自己在写库时为了兼容旧版本 Python 就不会使用那些最近新增的功能。例如用 pathlib 删除一个文件,无论文件存在与否: 因为 在最初库写成一段时间后,可能会决定放弃支持一些 Python 的旧版本。在这个例子里,如果我想放弃对 Python 3.7 的支持,如果有工具能找出现有代码中的可能为写法二的部分,提示我考虑写法一,那对维护工作就省心多了。那有这种代码检查吗? 题外话:分享一个解决我这个问题相反问题的工具:vermin。可以用来检查一个 Python 文件 /包所需要的最低 Python 版本。 |
Windows 11 的那个任务栏角溢出有办法和以前一样全部显示吗? Posted: 23 Oct 2021 04:02 PM PDT 难道这个功能被删除了? 网上找个了一个办法执行下面的命令可以打开设置菜单,但每次重启后就失效了...
|
请问如果要组建 100 个节点以上的集群,如何给机器配置免密登录呢?如果后期这个集群扩容到 200 个节点以上,该如何操作?有大佬提供下思路吗? Posted: 23 Oct 2021 10:31 AM PDT |
温州“遇见志同道合”线下沙龙 - 集合温州对互联网开发有热情的小伙伴 Posted: 23 Oct 2021 08:00 AM PDT 在温州的你,或是在北京、深圳、杭州、广州、上海的温州人的你, 是否也曾想要做一个互联网产品? 但苦于势单力薄,一直无法得到很好的执行。 时间流逝,不要等到年岁已高,再回过头,发现自己曾经的梦想早已经丢失不见,而后悔自己曾经没有去努力过。 众人拾柴火焰高,做互联网产品,需要坚强的团队,需要几个有热情、有能力的伙伴共同努力~ 温州其实有很多有热情的小伙伴,散落在温州各个角落,我希望通过这个活动能将大家聚集起来。 无论你是技术开发(前端 /后端)、UI 设计、产品经理、投资人, 欢迎加入,一起探讨,参加线下聚会,思想碰撞,遇见志同道合的伙伴, 或许就能成就自己一直想做的那个产品。 加微信 bigbod 添加的时候备注"温州互联网志同道合",我会拉你入群 将安排线下沙龙,一起探讨,一起交流 |
Language Server for Java ™ 1.0 在 VS Code 上正式发布! Posted: 23 Oct 2021 04:01 AM PDT 今天,我们很高兴与大家宣布:Language Server for Java™ 的 1.0 版本在 Visual Studio Code 上正式发布了!这是 Java 在 Visual Studio Code 上的一个重要里程碑,也是微软,红帽以及整个社区之间多年合作的结果。在这里我们要感谢所有提出过意见或者做过贡献的用户,谢谢! 发布亮点 当我们开始发布第一个版本时,我们的目标是在 Visual Studio Code 上提供最好的 Java 开发体验。此后,我们一直保持每月 1-2 次的发布周期,经历了多次迭代。在这个 1.0 版本中,我们想重点介绍以下新特色 Java 17 支持 我们会始终尽全力去支持 Java 语言提供的最新技术。在我们的 1.0 版本中,我们的 Java 插件现在正式提供对 Java 17 的支持 性能改进 性能提升也是本次发布的另一个亮点。由于 LSP规范中的新功能,我们能够推迟某些计算,从而在许多场景中为我们带来更好的性能。此外,更好的默认JVM选项可以用于改善更大更复杂项目的用户体验。我们还在很多特定场景做了细微的改进,以提高语言服务器的响应能力。 类继承体系 现在用户可以方便地在 Visual Studio Code 中轻松访问类继承体系!这是我们最近推出的一项功能,并且一直是 Java 社区中最热门的需求之一。 库源代码定位 目前,我们允许用户快速定位某个库的源代码,有时这非常有用。现在,我们已将其支持扩展到普通项目(即没有使用构建工具的项目)。只要库来自 Maven Central repo,我们就可以解析其来源。还支持更高级的配置。 更多代码相关操作 用户体验是我们继续改进的另一个领域。我们在新版本中提供了更多的代码操作来优化用户开发体验 Gradle Kotlin (.kts) 支持 尽管我们已经使用 Groovy 脚本支持 Gradle 项目,但我们不断听到社区需要更好的 Kotlin 支持,所以在新版本中我们对 Kotlin 提供了一些基本的支持。我们希望可以继续扩展这一领域,并在未来为 Kotlin 提供出色的体验 Visual Studio Code 的 Java 之旅 Language Server for Java™ 是 Java扩展包的基础,并提供了 Java 代码编辑、完成、重构、导航等核心体验。在过去的几年里,微软和红帽一直密切合作,不断为这个语言服务器添加新功能。我们还一直在微调语言服务器的性能,并通过修复 Bug 和添加新特性来提高稳定性。 除了主要的 Java 语言支持外,我们还基于语言服务器构建了各种 Java扩展,并扩展了 Visual Studio Code 上的 Java 开发体验,包括项目管理、对 Maven/Gradle 的构建工具支持、更好的测试支持等。这些努力背后的目标是在 Visual Studio Code 上提供最佳的 Java 开发体验。 展望未来 在未来,我们为 Visual Studio Code 上的 Java 语言支持有非常多的计划。其中一些包括:
Language Server for Java™ 的 1.0 版本是 Java 在 Visual Studio Code 上的重要里程碑,我们还有很长的路要走。微软和红帽将继续在 Java 语言支持方面进行合作和投入,我们致力于提供出色的 Java 开发体验。 与往常一样,您的反馈对我们的产品改进至关重要,因此请不要犹豫尝试我们的产品。您可以点击此链接开始使用 Visual Studio Code 学习 Java,也可以通过此链接获得最新的 Java 插件包。 |
Android 12 发布了,鸿蒙什么时候能 rebase 下主干 Posted: 23 Oct 2021 03:52 AM PDT 一直安卓 10 也不是事啊 |
You are subscribed to email updates from V2EX - 技术. To stop receiving these emails, you may unsubscribe now. | Email delivery powered by Google |
Google, 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States |
No comments:
Post a Comment