
https://www.cnblogs.com/lsgxeva/p/13382844.html
gradle里的项目和task,每个项目至少一个project,一个build.gradle就代表一个poject,每个project包含多少个task,task里包含很多action,action代码块里包含一些需要被执行的代码
编译过程关爱到了根据build相关文件聚合所有的project和task,执行task里的action,因为build.gradle里的task很多,所以用依赖逻辑保证执行顺序,几乎所有的task都需要依赖其他的task执行,没有依赖的task首先执行
编译分为三个阶段
初始化阶段:创建project对象,有多个gradle就创建多个project
配置阶段:这个阶段执行所有的编译脚本,同时创建项目的所有task,为执行阶段做准备
执行阶段:在这个阶段gradle根据传入的参数决定如何执行这些task,action的执行代码都在这里
实际上是一个app下面对应一个build.gradle,settings.gradle,然后下面是子app,子app有自己的build.gradle
setting.gradle定义哪些模块加入编译过程,单个模块的app是一般不需要这个文件,此文件在初始化的时候被执行
顶层的build.gradle里的配置用到所有的项目,典型配置里在buildscript里定义android编译工具的类路径仓库里的JCenter是一个maven库
allprojects里定义的属性会被应用到所有module里
apply插件里用了安卓的gradle插件,插件里提供编译打包等task
buildType里定义了编译类型,对调试和发布可以有不同配置
为了兼容旧版本产生
包括一些脚本文件和针对不同系统的运行文件,会自动下载对呀版本的运行文件
https://www.cnblogs.com/lsgxeva/p/13382844.html
可以使用gradlew列出所有的task和task的依赖
wrapper是我们使用命令行编译的开始
在as点击build,rebuild,clean的时候都触发了对应的gradle task
四个基本task
assemble可以把所有的buildtype(调试,发布)生成apk包
clean可以移除所有的编译输出文件,比如apk
check可以执行lint监测编译
build同时执行assemble和check命令
可以通过buildconfig.debug判断当前版本是否是debug版本,gradle编写语言是groovy,一种jvm语言,groovy可以生成java字节码类
可以加入项目链接
如果仓库有密码可以传入用户名和密码
还可以用相对路径配置一下本地仓库,通过配置项目里存在的静态文件夹作为本地仓库
库名称由组名,库名称和版本号组成
为了保证依赖库是最新状态可以使用通配符+,但是会导致每次都要用网络请求查看是否有最新版本导致编译过慢
也可以使用file()添加文件依赖,如果有多个jar包依赖可以放到文件夹里使用filetree引用
配置本地的so库可以
不方便直接引用项目需要使用文件形式引入就把项目打包成aar文件
这样我们在项目下新建aars文件夹之后配置一下仓库,引用的时候
在debug和release的时候可能需要配置不同的服务器地址,打包市场渠道包的时候可能要打免费版收费版或内部版外部版程序
这是有buildtype区分
可以创建新的编译类型
gradle默认创建一个新的资源集,可以建立不同的文件夹,里面放上需要的不同资源和代码
针对同一份源码编译不同的程序编译收费和免费版可以使用product flavors
想build type一样也是可以有不同文件夹和配置
复杂情况可能需要多个product的未读进行组合,比如想要颜色和价格两个维度组合,先创建维度,之后是维度细分
buildtype里的优先级最大
可以开启并行编译加快编译
可以开启守护进程,二次编译的时候重用进程
可以使用shrinkresources渠道编译的时候不需要的资源
用shrinkReleaseResources命令可以看懂减少了哪些资源
一些需要动态加载的资源需要向Progard的一样对资源进行keep操作
可以再res/raw/下建立一个keep.xml文件keep资源
对一些特殊文件或文件夹,如国际化的资源文件,屏幕适配资源,如果已经确定了某种型号不需要重新适配可以去掉不适配的资源
在groovy里没有固定类型,变量直接使用def引用
使用单引号只是字符串,双引号里面还可以放变量$变量名
方法也使用def声明,不指定返回值就返回最后一行代码的值
默认所有类和方法都是公共的,所有类的字段是private
通过new得到实例来引用
类里生命的字段都会默认生成对应的settinggetter方法,groovy方法调用时可以没有括号的,也不需要分号结尾,也可以直接调用
可以通过instance.greeting方式拿到字段值,也是通过get方法的
在map,collections
定义一个列表遍历列表使用each
定义一个map,获取map使用get或[]
闭包,匿名内部类,支持类似lamda形式的语法调用
task执行的时候action依次执行
可以在里面写dolast和dofirst方法
关于Task 的依赖有两种,must RunAfter和dependsOn
must必须按顺序加入之后顺序之后,后者是同时执行的
新建的时候选择新建模块–android library–之后在minimum sdk里是api16
之后吧代码传到library里上传github
然后发布代码就可以发布了
https://developer.android.com/training/volley?hl=zh-cn
是一个可以让应用更轻松更快联网的http库
可以自动网络请求调度,可以有多个并发网络链接
有透明磁盘和具有标准http缓存一致性的内存响应缓存
支持请求的优先级,可以取消单个请求并且设置要取消的请求的时间段或范围
可以自定义重试和退避的时间
强大的排序功能,可以轻松从网络异步提取的数据正确填充界面
可以用结构化数据形式获取搜索结果页面,可以轻松集成各种协议,开箱后就支持原始字符串图片和json
不适合下载大量内容的操作和流式传输操作,在解析过程里会把所有的响应存储在内存里,大量下载内容的操作需要使用downloadManager等替代方法
dependencies {
...
implementation 'com.android.volley:volley:1.1.1'
}
https://blog.csdn.net/geyuecang/article/details/105270669
implementation引入,gradle会把依赖项添加到编译类路径,并且吧依赖项打包到构建输出,其他模块只有在运行的时候才可以使用这个依赖项
使用这个依赖项配置代替api或已经弃用的compile可以缩短构建时间减少构建系统需要重新编译的模块数,比如implementation依赖项更改了其api,gradle只重新编译改依赖项以及直接依赖于它的模块
api引入
gradle不仅吧依赖项添加到编译类路径还添加到构建输出里,一个模块包涵api依赖项的时候,会让gradle了解该模块需要以传递方式导出到其他模块,让其他模块运行和编译的时候都可以使用这个依赖项
类似于compile,但是只能对需要以传递方式导出到其他上游消费者的依赖项使用它,如果api依赖项更改了其外部api,gradle会在编译的时候重新编译所有访问该依赖项的模块,会显著增加构建时间
https://blog.csdn.net/ezconn/article/details/112851615
com.android是android内置的
检查apk文件结构
对于 ARM 架构,32 位库位于 armeabi-v7a 中。 对应的 64 位库则位于 arm64-v8a 中。
对于 x86 架构,32 位库位于 x86 中,64 位库则位于 x86_64 中。
https://developer.android.com/games/optimize/64-bit?hl=zh-cn
https://www.csdn.net/tags/NtzaQg1sNjc5ODAtYmxvZwO0O0OO0O0O.html
有一个项目需要把coocos引擎升级到支持64位的
是android系统里的一种文件,和apk以及jar格式类似
就是所优化后的安卓版exe文件
在java程序编译成class之后还需要使用dx工具吧所有class文件整合为一个dex文件让各个类共享数据,是jar文件大小的一半
实际上就是在pc使用的java虚拟机可以运行class文件,android系统的davlik虚拟机运行dex文件
使用反编译工具可以获取java源码,修改dex文件可以更好的防破解
java,C和C++都可以生成dex文件
生成
IDE可以帮助build生成dex文件,也可以在class文件下使用dx --dex --output指令生成dex文件
dx --dex --output TestMain.dex TestMain.class
dex文件在手机上可以使用adb运行
先使用adb push吧生成的dex文件push到手机的一个目录里,之后使用adb shell链接手机之后执行dalvikvm -cp命令执行该文件,不需要写dex后缀
https://blog.csdn.net/tabactivity/article/details/78950379
https://segmentfault.com/a/1190000022579808?utm_source=tag-newest
npm install 执行完毕后,我们可以在 nodemodules 中看到所有依赖的包
插件化开发的时候想让app快速启动,需要让主dex只包含首页和基础模块,其他放到从dex里
所以先让项目支持multidex
https://blog.csdn.net/hujin2017/article/details/102719506
android {
defaultConfig {
// 设置支持multidex
multiDexEnabled true
}
}
dependencies {
//引入对multidex支持的库
compile 'com.android.support:multidex:1.0.1'
}
在自定义的application中的attachBaseContext方法中添加如下代码:
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
明确主dex文件中要包含哪些class文件,明确后,在module的build.gradle所在的目录下,新建一个maindexlist.txt文件,并将这些class文件所在的路径都写入到这个文件中。
https://segmentfault.com/a/1190000040411873?utm_source=sf-similar-article
在build.gradle里添加依赖是使用的gradle抓取方式
默认是谷歌和jcenter两个库,还可以自己添加maven库
下载jar包到模块的libs下
然后右键Add as library…
或者在dependencies里
导入本地库
implementation files('libs/cglib-for-android.jar')
导入这个模块下所有的jar包
implementation fileTree(dir: 'libs',includes: ['*.jar','*.aar'])
https://blog.csdn.net/qq_32534441/article/details/107069737
一次性引入libs目录下所有jar文件
compile fileTree(include: ['*.jar'], dir: 'libs')
https://blog.csdn.net/Deemons/article/details/77588327
as是从文件定义的仓库服务器下载library的
库的字符串形式包涵三个部分,groupid+library名称+版本号
as下载之后和我们的项目一起编译
一般在as本地缓存库里

远程依赖到本地as缓存之后有这几个文件
在aar的源码里不管使用 implementation 或者 api,打成 aar 包之后,当我们通过 gradle 脚本上传到服务器时,我们可以通过 pom.project 来将 aar 源码中的依赖生成 pom.xml 文件。这些依赖配置项会通过脚本,被转义成 maven 中的依赖配置项
是子模块配置文件,单项目构建可以不用,多项目必须用
根目录下的可以配置所有的module
rootProject.name = 'project-root’指定父模块的名称
include用于加载子系统以及模块
gradle工作流程
初始化的时候先解析settings.gradle
配置阶段,解析每个build.gradle,只解析不执行各个build.gradle里的task
解析完形成一个task有向图方便后续执行task
在所有project配置完之后有一个回调.afterEvaluate,表示所有的模块都已经配置完了。
之后开始执行task
plugins里是需要引入的插件
// Spring boot
id 'org.springframework.boot' version '2.1.6.RELEASE'
// Maven
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
仓库配置里
仓库用于存储下载的依赖或远程或缓存
https://blog.csdn.net/qq_15345551/article/details/121518218?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2aggregatepagefirst_rank_ecpm_v1~rank_v31_ecpm-4-121518218.pc_agg_new_rank&utm_term=Android+%E5%88%A4%E6%96%AD%E6%98%AF%E5%90%A6%E6%94%AF%E6%8C%8164%E4%BD%8D%E6%9E%B6%E6%9E%84&spm=1000.2123.3001.4430
pk构建的过程中,会执行{merge[BuildVariants]NativeLibs}这个task去合并所有的依赖,包括远程和本地
通过dependencyInsight,我们可以查找到这个so文件最顶层的依赖
https://blog.csdn.net/Duker_tec/article/details/122078281

就是动态链接库,是linux系统里的,是linux系统的可执行文件,共享库文件
可以让多个程序共享一个动态链接库
app的二进制接口定义了二进制文件(包括so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐,到可用的系统函数库,每个系统架构对应一个abi
项目只要使用ndk就生成so文件
ndk是吧C变成so文件,sdk是吧java变成so文件
Native Libs Monitor可以帮助看到apk用了哪些so文件,以及so文件来源于哪些函数库或框架
apk包打包之后使用PackageManager安装,在小于Android 5.0的系统中,.so文件位于app的nativeLibraryPath目录中;在大于等于Android 5.0的系统中,.so文件位于app的nativeLibraryRootDir/CPU_ARCH目录中。
1.在仓库提issue
2.看作者简介
https://blog.csdn.net/weixin_44424296/article/details/114460923
https://blog.csdn.net/yang123465/article/details/80677753
引用的第三方库的支持库版本低于(或者不一致)app build.gradle中的支持库版本
android{
configurations.all {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
def requested = details.requested
if (requested.group == 'com.android.support') {
if (!requested.name.startsWith("multidex")) {
details.useVersion '27.7.1'
}
}
}
}
}
https://www.csdn.net/tags/MtTaEg0sNjM5NDk5LWJsb2cO0O0O.html
可以获取所有gradle版本,可以再项目的build.gradle里配置统一的版本号
在模块的default配置里可以引用project的build.gradle里的项目别名和里面的关键字指定统一的版本名等
注解处理器是javac的一个工具,可以再编译的时候扫描和处理注解,获取到注解和被注解对象的相关信息之后根据注解自动生成java代码
https://blog.csdn.net/wusj3/article/details/88415798
gradle里的多渠道管理可以再里面设置测试用的appid,或者不同url的根地址
然后一些第三方sdk申请到的appkey在manifest文件里使用meta-data标签设置value和name,可以先写一个占位符,之后在gradle的defaultconfig里配置
gradle是纯java写的
可以使用BuildConfig.DEBUG决定是否打印log,buildConfigField(“boolean”, “isBeta”, “true”)
https://blog.csdn.net/lyabc123456/article/details/81557220
https://blog.csdn.net/lazyer_dog/article/details/54581148
先打包资源变成R.java
之后处理AIDL文件生成相应的java文件,没有用的aidl文件就跳过
编译项目里所有的Java文件为class文件
吧class文件变成dex文件
打包成apk
对apk进行签名,keysrore,签名完才可以安装到设备上
对签名完的文件进行对齐处理
https://developer.android.com/distribute/best-practices/develop/64-bit
https://blog.csdn.net/ouyang_peng/article/details/51168072
https://www.cnblogs.com/xqxacm/p/5897435.html