——》个人平时笔记,看到的同学欢迎指正错误,文中多处摘录于各大博主精华、书籍
一,整个apk打包的流程图:
1、使用Android Asset Packaging Tool(aapt、aapt2) ,将AndroidManifest.xml和res下的资源编译生成R.java文件,这样java文件就可以去引用资源了 - 使用aidl 工具去生成对应的Java interfaces - 将src和通过aapt生成的R.java,.aidl文件通过javaC命令去生成.class 文件 , 使用dex tool 将class文件转化成Dalvik bytecode文件。这时候要将所有class文件和包括第三方的jar包, 所有没有编译过的图片和编译过的图片(compiled resources)以及.dex文件传给apkbuilder去打包成.apk ,最后采用zipalign tool 打入签名生成可运行的apk安装包。
aapt2是在aapt上做了优化。Android Gradle Plugin3.0.0或者更高版本默认开启aapt2。当然也可以在配置文件中手动关闭aapt2。在gradle.properties设置android.enableAapt2=false即可, aapt2将原先的资源编译打包过程拆分成了两部分,即编译和链接。
编译:将资源文件编译为二进制格式文件
链接:将编译后的所有文件合并,打包成一个单独文件
aapt2打包可以很好的提升资源的编译性能,比如只有一个资源文件发生改变时,你只需要重新编译改变的文件,然后将其与其他未改变的资源进行链接即可。而之前的aapt是将所有资源进行merge,merge完后将所有资源进行编译,产生一个资源apk文件,该文件是一个压缩包,这样带来的后果就是即使只改变了一个资源文件,也要进行全量编译。
2、Android 运行环境主要指的虚拟机技术——Dalvik(Android 开发简介-系统架构)。Android中的所有Java程序都是运行在Dalvik VM上的。Android上的每个程序都有自己的线程,DVM只执行.dex的Dalvik executable 文件。每个Android应用在底层都对应有一个独立的DVM实例并在其解释下执行。
虽然DVM也是用Java编程语言,Dalvik虚拟机和一般JAVA虚拟机(Java VM)并不兼容,他们两个的区别是JVM标准执行的是.class的字节码(bytecode ),而是DVM执行的是其专有的(.dex)执行文件。在编译过程中,Java把类编译成一个或多个.class byte code 文件,然后打包到jar中,JVM会从中jar文件中获得相应的.class文件和JRE字节码。 Android VM虽然也是是用Java语言进行编程, Java程序通过编译后,还需要通过SDK中的dex工具.class文件转化打包成.dex格式文件,DVM再从其中读取指令和数据。
每一个应用程序即一个进程(Linux的一个Process)。 二者最大的区别在于Java VM是以基于栈的虚拟机(Stack-based),而Dalvik是基于寄存器的虚拟机(Register-based)。 显然,后者最大的好处在于可 以根据硬件实现更大的优化,这更适合移动设备的特点。
DVM非常适合在移动终端上使用,与PC相比,它不需要很快的CPU和大量的内存空间. Google的测算显示,64MB的内存已经能让系统正常运转了。 其中24MB被用于底层系统的初始化和启动。另外20MB被用于启动高层服务。DVM有如下特征:
》1、使用专有的.dex格式:
原因是 :
(1)、java类文件在编译过后,会产生至少一个.class文件包含大量陈余信息,dex文件格式会把所有 的.class文件内容整合到一个.dex文件中。通常一个应用apk只有一个classes.dex,但是开启了multiDexEnabled true分包可以生成多个.dex文件。即减少了整体文件的尺寸和IO操作,也提高了类的查找速度。增加了对新的操作码的支持,使文件结构尽量简洁,使用等长的指令,借以提高解析速度。
(1)尽量扩大只读结构的大小,借以提高跨进程的数据共享。
》2、dex的优化:dex文件的结构是紧凑的,但是如果想提高运行时的性能,就需要对dex文件进行进一步的优化,这些优化针对以下几个方面:
(1)、验证dex文件中的所有类对一些特定的类和方法里面的操作码进行优化
(2)、调整所有的字节序(Little_endian)和对齐结构中的每一个域
》3、基于寄存器:基于寄存器的虚拟机虽然比基于堆栈的虚拟机在硬件通用性上要差一些,但是它的代码执行效率却更好。每一个Android应用都运行在它自己的DVM实例中,每一个DVM实例都是一个独立的进程空间。 所有的Android应用的线程都对应一个Linux线程,DVM因此可以更多地依赖操作系统的线程调度和管理机制。不同的应用在不同的进程空间里运行,不同的应用都是用不同的Linux用户来运行以最大程度地保户应用程序的安全性和独立性。
3、ART(Android Runtime)是Android 4.4发布的,用来替换Dalvik虚拟,Android 4.4默认采用的还是DVM,系统会提供一个选项来开启ART。在Android 5.0时,默认采用ART,DVM从此退出历史舞台。
二、SO库注意
对于一个cpu是arm64-v8a架构的手机,它运行app时,进入jnilibs去读取库文件时,先看有没有arm64-v8a文件夹,如果没有该文件夹,去找armeabi-v7a文件夹,如果没有,再去找armeabi文件夹,如果连这个文件夹也没有,就抛出异常;
如果有arm64-v8a文件夹,那么就去找特定名称的.so文件,注意:如果没有找到想要的.so文件,不会再往下(armeabi-v7a文件夹)找了,而是直接抛出异常。
Q1: 只适配了armeabi-v7a,那如果APP装在其他架构的手机上,如arm64-v8a上,会蹦吗?
A: 不会,但是反过来会。因为armeabi-v7a和arm64-v8a会向下兼容:
只适配armeabi的APP可以跑在armeabi,x86,x86_64,armeabi-v7a,arm64-v8上
只适配armeabi-v7a可以运行在armeabi-v7a和arm64-v8a
只适配arm64-v8a 可以运行在arm64-v8a上
原文链接:https://blog.csdn.net/weixin_42600398/article/details/118601134