当前位置:网站首页>Apk slimming compression experience
Apk slimming compression experience
2022-06-25 00:21:00 【BY-91】
List of articles
- Unity of resources
- Use jpg Format picture
- Use webp Format picture
- Use shape Background and selector Coloring scheme
- Online material library
- lint Check
- Delete unnecessary so library
- Get rid of useless language resources
- Turn on confusion
- Turn on shrinkResources Remove useless resources
- Use zipAlign
- Use AndResGuard Compress resource files
- compile webp decoder
Unity of resources
Try to use the same set of resources for a project , For the great logarithm APP Come on , Just one set of design drawings is enough . Given the current trend in resolution , It is suggested that 720p Resources for , Put it in xhdpi Catalog .
Compared to multiple sets of resources , Use only 720P A set of resources for , There's not much visual difference , The same is true of the products of many large companies , But it can significantly reduce the size of resource consumption , By the way, it can also reduce the workload of the designer . No xhdpi Delete all the directories of , Instead, it emphasizes that it is enough to keep a set of design resources .
Compress the resource image before importing it , Don't use the original ( Don't use... Directly UI Cut the original picture )
Use jpg Format picture
If it's not transparent for a large image ,jpg Will compare png There is a significant advantage in the size of , Although not absolutely , But it's usually reduced to more than half . On the startup page , Activity pages and other large picture display areas use jpg It would be a very wise choice .
Use webp Format picture
- WebP It is a picture file format that supports lossy compression and lossless compression , according to Google Test of , After lossless compression WebP Than PNG There are fewer documents 26% Volume , Lossy compressed WebP The picture compares to the equivalent quality index of JPEG There are fewer pictures 25%~34% Volume .
- webp Support transparency , Compression ratio jpg Higher, but the display effect is not inferior to jpg, Official evaluation quality The parameter is equal to 75 The best balance .
be relative to jpg、png,webp As a new image format , Be limited to android It's not widely used in mobile phones yet . from Android 4.0+ Start native support , But transparency is not supported , until Android 4.2.1+ To support the display of transparent webp, Pay special attention when using . - according to Google Test of , at present WebP And JPG Comparison , Coding is slow 10 times , Slow decoding speed 1.5 times , The problem lies in 1.5 Whether the decoding speed of 10 times will affect the user experience . At the same time, due to the reduction of file size , Shorten the loading time , Page rendering speeds up . meanwhile , As the number of pictures increases ,WebP Page loading speed is relatively JPG The page is growing faster . therefore , Use WebP There are basically no technical barriers .

Use shape Background and selector Coloring scheme
For some simple graphics or background images , Instead of introducing the image itself, you can customize the drawing method .
For some pictures with the same shape but different colors , have access to selector File to implement .
Online material library
If there are many or a group of graphics that need to be introduced , For example, facial expression bag , Consider using the online introduction method , Save local space . But it also increases code complexity and APP Flow consumption .
lint Check
Code scanning tools , Can help you find and correct the quality of the code structure , for example , If XML The resource file contains unused namespace , It's not just taking up space , And it will cause unnecessary treatment .
Official website address
Terminal execution command
gradlew lint
Or you can select Analyze > Inspect Code, Manually run the configured lint And others IDE Check . The results will be displayed in Inspection Results Window , If there are unused resources that can be deleted .
Delete unnecessary so library
Basically armable Of so It's also compatible armable-v7 Of ,armable-v7a The library will greatly improve the graphics rendering , If there is no such requirement , Can be streamlined . There are very few devices that can Crash, Test passed, reuse .x86 Under bag so stay x86 The model of mobile phone is needed , If the product doesn't work, the requirements in this respect can also be simplified . The actual working configuration is that you can choose to keep only armable、armable-x86 Under the so file .
Get rid of useless language resources
Only Chinese and English language resources are reserved , For some support multilingual SDK.
android {
defaultConfig {
resConfigs "zh-rCN", "en-rUS"
}
}
Turn on confusion
android {
defaultConfig {
minifyEnabled true
}
}
Turn on shrinkResources Remove useless resources
The unused resource files will be removed when they are packaged , But the source code won't change , However, the actual measurement of this scheme is correct for apk The optimization of weight loss will not necessarily have a positive effect , You can use . But you should use it at the same time as the previous step , It is invalid to use it alone .
android {
buildTypes {
release {
shrinkResources true
}
}
}
Use zipAlign
Tools for resource alignment ( Align to a four byte boundary and access it in units ), Make resources more efficient when they are accessed Be able to optimize packaged applications , Yes, the system and APP The interaction between them is more efficient , But yes apk The effect of slimming is not significant .
android {
buildTypes {
release {
zipAlignEnabled true
}
}
}
Use AndResGuard Compress resource files
The above ways , It mainly deals with the resource itself and compresses the code , however apk The resources in are not operating too much . AndResGuard Wechat exit is a way to help you shrink APK Tools of size , But only for resources ( Mainly res) There is no compilation involved . He will shorten the originally lengthy resource path , For example res/drawable/wechat Turn into r/d/a
Official website and introduction method
Add a white list of confusion : Specify resource path rules that do not need to be obfuscated , Mainly some third parties SDK, Because there are some SDK Reference to the corresponding resource file , If you confuse it , The corresponding resource file cannot be found , appear crash, So we can't confuse the resource files . The white list links to ;
When importing, you can also choose to customize gradle The way
After the configuration is completed, use the following method to print the required apk
The effect is similar to that of wechat apk The effect of compression . hold res The document was changed as follows r The form of the folder , And the compression effect is good .
compile webp decoder
Mobile phone manufacturers bring their own webp The decoder is basically for Android 4.3 The above models ,4.3 Here are some questions , So we can webp Compile the source code of , Pack it up so library , Use your own decoder .
download webp The source code is placed in the created jni Under the folder
libwebp Source code download address 

introduce jar package
take libwebp.jar Introduced into Engineering
Android.mk To configure
- Configuration allows compilation of the current source directory
ENABLE_SHARED:=1

- because libwebp.jar Need to use wig/libwebp_java_wrap.c In the document jni Method , So we need to import this file into Android.mk File to configure
# libwebp
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
$(dsp_enc_srcs) \
$(enc_srcs) \
$(utils_enc_srcs) \
swig/libwebp_java_wrap.c \

establish Application.mk
APP_ABI := armeabi-v7a
APP_PLATFORM := android-14

Design of compiler and decoder so library
stay libwebp Open in the source directory cmd, Use ndk To compile the files in the directory , Generate so library
C:\SDK\ndk\21.3.6528147\ndk-build.cmd NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk APP_BUILD_SCRIPT=Android.mk
After compiling, import so The library files
contrast png,jpeg,webp The speed of encoding and decoding

The relevant code is as follows
defaultConfig {
applicationId "com.bliss.yang.webpapp"
minSdkVersion 19
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ndk {
abiFilters "armeabi-v7a"//, add to ndk Support for
}
}
companion object{
init {
System.loadLibrary("webp")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// webp Decoding speed Encoding speed
var l = System.currentTimeMillis()
BitmapFactory.decodeResource(resources, R.drawable.splash_bg_webp)
Log.e(TAG, " decode webp Image time consuming :" + (System.currentTimeMillis() - l))
l = System.currentTimeMillis()
BitmapFactory.decodeResource(resources, R.drawable.splash_bg_jpeg)
Log.e(TAG, " decode jpeg Image time consuming :" + (System.currentTimeMillis() - l))
l = System.currentTimeMillis()
var bitmap = BitmapFactory.decodeResource(resources, R.drawable.splash_bg_png)
Log.e(TAG, " decode png Image time consuming :" + (System.currentTimeMillis() - l))
// code png
var bitmap1 = BitmapFactory.decodeResource(resources, R.drawable.splash_bg_png)
l = System.currentTimeMillis()
compressBitmap(bitmap1, CompressFormat.PNG, Environment
.getExternalStorageDirectory().toString() + "/test.png")
Log.e(TAG, "-------> code png Image time consuming :" + (System.currentTimeMillis() - l))
// code jpeg
bitmap1 = BitmapFactory.decodeResource(resources, R.drawable.splash_bg_jpeg)
l = System.currentTimeMillis()
compressBitmap(bitmap1, CompressFormat.JPEG, Environment
.getExternalStorageDirectory().toString() + "/test.jpeg")
Log.e(TAG, "-------> code jpeg Image time consuming :" + (System.currentTimeMillis() - l))
// code webp
bitmap1 = BitmapFactory.decodeResource(resources, R.drawable.splash_bg_webp)
l = System.currentTimeMillis()
compressBitmap(bitmap1, CompressFormat.WEBP, Environment
.getExternalStorageDirectory().toString() + "/test.webp")
Log.e(TAG, "-------> code webp Image time consuming :" + (System.currentTimeMillis() - l))
// Compiled decoder
l = System.currentTimeMillis()
decodeWebp()
Log.e(TAG, "libwebp Decoding a picture takes time :" + (System.currentTimeMillis() - l))
l = System.currentTimeMillis()
encodeWebp(bitmap)
Log.e(TAG, "libwebp It takes time to encode pictures :" + (System.currentTimeMillis() - l))
}
private fun encodeWebp(bitmap: Bitmap) {
// obtain bitmap Wide and high
val width = bitmap.width
val height = bitmap.height
// get bitmap Medium ARGB data nio
val buffer: ByteBuffer = ByteBuffer.allocate(bitmap.byteCount)
bitmap.copyPixelsToBuffer(buffer)
// code get webp Format file data 4 *width
val bytes: ByteArray = libwebp.WebPEncodeRGBA(buffer.array(), width, height, width * 4, 75F)
var fos: FileOutputStream? = null
try {
fos = FileOutputStream(Environment
.getExternalStorageDirectory().toString() + "/libwebp.webp")
fos.write(bytes)
} catch (e: Exception) {
e.printStackTrace()
} finally {
if (null != fos) {
try {
fos.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
}
private fun decodeWebp(): Bitmap? {
@SuppressLint("ResourceType") val `is`: InputStream = resources.openRawResource(R.drawable.splash_bg_webp)
val bytes = stream2Bytes(`is`)
// take webp Format data into argb
val width = IntArray(1)
val height = IntArray(1)
try {
`is`.close()
} catch (e: IOException) {
e.printStackTrace()
}
val argb: ByteArray = libwebp.WebPDecodeARGB(bytes, bytes.size.toLong(), width, height)
// take argb byte The array is converted to int Array
val pixels = IntArray(argb.size / 4)
ByteBuffer.wrap(argb).asIntBuffer().get(pixels)
// get bitmap
return Bitmap.createBitmap(pixels, width[0], height[0], Bitmap.Config.ARGB_8888)
}
fun stream2Bytes(`is`: InputStream): ByteArray {
val bos = ByteArrayOutputStream()
val buffer = ByteArray(2048)
var len: Int
try {
while (`is`.read(buffer).also { len = it } != -1) {
bos.write(buffer, 0, len)
}
} catch (e: IOException) {
e.printStackTrace()
}
return bos.toByteArray()
}
private fun compressBitmap(bitmap: Bitmap, format: CompressFormat, file: String) {
var fos: FileOutputStream? = null
try {
fos = FileOutputStream(file)
} catch (e: FileNotFoundException) {
e.printStackTrace()
}
bitmap.compress(format, 75, fos)
if (null != fos) {
try {
fos.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
边栏推荐
- WordPress add photo album function [advanced custom fields Pro custom fields plug-in series tutorial]
- 【排行榜】Carla leaderboard 排行榜 运行与参与手把手教学
- 有趣的checkbox计数器
- Overview of medium and low speed aerospace electronic bus
- Approaching harvest moon:moonbeam DFI Carnival
- Meta & Berkeley proposed a universal multi-scale visual transformer based on pooled self attention mechanism. The classification accuracy in Imagenet reached 88.8%! Open source
- 干接点和湿接点
- Go crawler framework -colly actual combat (I)
- C程序设计专题 15-16年期末考试习题解答(上)
- 软件测试与游戏测试文章合集录
猜你喜欢

时间统一系统

无人驾驶: 对多传感器融合的一些思考

Reservoir dam safety monitoring

Im instant messaging development application keeping alive process anti kill
@mysql

∞ symbol line animation canvasjs special effect

为什么越来越多的实体商铺用VR全景?优势有哪些?

Signal integrity (SI) power integrity (PI) learning notes (XXV) differential pair and differential impedance (V)

On the difficulty of developing large im instant messaging system

部门新来的00后真是卷王,工作没两年,跳槽到我们公司起薪18K都快接近我了
随机推荐
Color gradient gradient color collection
【面试题】instancof和getClass()的区别
同济、阿里获CVPR最佳学生论文,李飞飞获黄煦涛奖,近6000人线下参会
C program design topic 15-16 final exam exercise solutions (Part 1)
无人驾驶: 对多传感器融合的一些思考
Current situation analysis and development trend prediction report of hesperidase industry in the world and China from 2022 to 2028
干接点和湿接点
Im instant messaging development application keeping alive process anti kill
How can I persuade leaders to use DDD to construct the liver project?
D omit parameter name
Signal integrity (SI) power integrity (PI) learning notes (XXV) differential pair and differential impedance (V)
Analysis report on operation mode and future development of global and Chinese methyl cyclopentanoate industry from 2022 to 2028
Go crawler framework -colly actual combat (III) -- panoramic cartoon picture capture and download
linux 系统redis常用命令
Wx applet jump page
MySQL日志管理
Fuxin Kunpeng joins in, and dragon lizard community welcomes a new partner in format document technical service
时间统一系统
为什么生命科学企业都在陆续上云?
Hyperledger Fabric 2. X dynamic update smart contract







