https://www.cnblogs.com/lsgxeva/p/13382844.html
是android 的主流编译工具
以前gradle因为编译过程的原因有点慢
与android studio关系紧密
对简单程序基本不需要配置代码,值使用android studio就可以完成编译和运行
对于复杂的多人合作项目会使用一些个性化配置提高开发效率
比如自定义一下编译包名字,对同一产品编译出免费版和付费版apk等
android studio 2.0发布之后,gradle升级为instant run,编译速度逆天
gradle编译周期
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的执行代码都在这里
gradle文件
实际上是一个app下面对应一个build.gradle,settings.gradle,然后下面是子app,子app有自己的build.gradle setting.gradle定义哪些模块加入编译过程,单个模块的app是一般不需要这个文件,此文件在初始化的时候被执行 顶层的build.gradle里的配置用到所有的项目,典型配置里在buildscript里定义android编译工具的类路径仓库里的JCenter是一个maven库 allprojects里定义的属性会被应用到所有module里 apply插件里用了安卓的gradle插件,插件里提供编译打包等task buildType里定义了编译类型,对调试和发布可以有不同配置
gradle wrapper
为了兼容旧版本产生 包括一些脚本文件和针对不同系统的运行文件,会自动下载对呀版本的运行文件 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
可以通过buildconfig.debug判断当前版本是否是debug版本,gradle编写语言是groovy,一种jvm语言,groovy可以生成java字节码类
repositories
可以加入项目链接 如果仓库有密码可以传入用户名和密码 还可以用相对路径配置一下本地仓库,通过配置项目里存在的静态文件夹作为本地仓库
Dependencies
库名称由组名,库名称和版本号组成 为了保证依赖库是最新状态可以使用通配符+,但是会导致每次都要用网络请求查看是否有最新版本导致编译过慢 也可以使用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资源 对一些特殊文件或文件夹,如国际化的资源文件,屏幕适配资源,如果已经确定了某种型号不需要重新适配可以去掉不适配的资源
自定义task
groovy
在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必须按顺序加入之后顺序之后,后者是同时执行的
impletation里的依赖是怎样引入的
建立自己的android库
新建的时候选择新建模块–android library–之后在minimum sdk里是api16 之后吧代码传到library里上传github 然后发布代码就可以发布了
volley使用概览
https://developer.android.com/training/volley?hl=zh-cn 是一个可以让应用更轻松更快联网的http库 可以自动网络请求调度,可以有多个并发网络链接 有透明磁盘和具有标准http缓存一致性的内存响应缓存 支持请求的优先级,可以取消单个请求并且设置要取消的请求的时间段或范围 可以自定义重试和退避的时间 强大的排序功能,可以轻松从网络异步提取的数据正确填充界面 可以用结构化数据形式获取搜索结果页面,可以轻松集成各种协议,开箱后就支持原始字符串图片和json 不适合下载大量内容的操作和流式传输操作,在解析过程里会把所有的响应存储在内存里,大量下载内容的操作需要使用downloadManager等替代方法
dependencies {
...
implementation 'com.android.volley:volley:1.1.1'
}
implementation和api的区别
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和com.mcxiaoke
com.android是android内置的
确定应用是否支持64位库
检查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
编译报错多个第三方库没有64位架构包
https://www.csdn.net/tags/NtzaQg1sNjc5ODAtYmxvZwO0O0OO0O0O.html 有一个项目需要把coocos引擎升级到支持64位的
apk包里的dex文件
是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
node_modules 目录结构
https://segmentfault.com/a/1190000022579808?utm_source=tag-newest npm install 执行完毕后,我们可以在 nodemodules 中看到所有依赖的包
第三方库是否支持64位架构的问题
怎么判断第三方库/sdk是否支持64位架构
build的时候把一些包变成dex文件
插件化开发的时候想让app快速启动,需要让主dex只包含首页和基础模块,其他放到从dex里 所以先让项目支持multidex https://blog.csdn.net/hujin2017/article/details/102719506
android {
defaultConfig {
multiDexEnabled true
}
}
dependencies {
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本地缓存库里
pom,aar,jar
远程依赖到本地as缓存之后有这几个文件 在aar的源码里不管使用 implementation 或者 api,打成 aar 包之后,当我们通过 gradle 脚本上传到服务器时,我们可以通过 pom.project 来将 aar 源码中的依赖生成 pom.xml 文件。这些依赖配置项会通过脚本,被转义成 maven 中的依赖配置项
settings.gradle
是子模块配置文件,单项目构建可以不用,多项目必须用 根目录下的可以配置所有的module rootProject.name = 'project-root’指定父模块的名称 include用于加载子系统以及模块 gradle工作流程 初始化的时候先解析settings.gradle 配置阶段,解析每个build.gradle,只解析不执行各个build.gradle里的task 解析完形成一个task有向图方便后续执行task 在所有project配置完之后有一个回调.afterEvaluate,表示所有的模块都已经配置完了。 之后开始执行task
build.gradle
plugins里是需要引入的插件
id 'org.springframework.boot' version '2.1.6.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
仓库配置里 仓库用于存储下载的依赖或远程或缓存
Android studio插件,检查依赖的so是否支持64位(或者其他的abi)
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文件最顶层的依赖
64位打包的apk里的so文件特别少
https://blog.csdn.net/Duker_tec/article/details/122078281
.so文件
就是动态链接库,是linux系统里的,是linux系统的可执行文件,共享库文件 可以让多个程序共享一个动态链接库 app的二进制接口定义了二进制文件(包括so文件)如何运行在相应的系统平台上,从使用的指令集,内存对齐,到可用的系统函数库,每个系统架构对应一个abi 项目只要使用ndk就生成so文件 ndk是吧C变成so文件,sdk是吧java变成so文件 Native Libs Monitor可以帮助看到apk用了哪些so文件,以及so文件来源于哪些函数库或框架
Native Libs Monitor在as里的使用
apk打包原理
apk包打包之后使用PackageManager安装,在小于Android 5.0的系统中,.so文件位于app的nativeLibraryPath目录中;在大于等于Android 5.0的系统中,.so文件位于app的nativeLibraryRootDir/CPU_ARCH目录中。
直接/间接
联系github作者
1.在仓库提issue 2.看作者简介 https://blog.csdn.net/weixin_44424296/article/details/114460923
gradle升级instant run
强制让所有模块都用相同的支持库版本
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'
}
}
}
}
}
gradle常用操作
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”)
打包64位
https://blog.csdn.net/lyabc123456/article/details/81557220
apk打包原理
https://blog.csdn.net/lazyer_dog/article/details/54581148 先打包资源变成R.java 之后处理AIDL文件生成相应的java文件,没有用的aidl文件就跳过 编译项目里所有的Java文件为class文件 吧class文件变成dex文件 打包成apk 对apk进行签名,keysrore,签名完才可以安装到设备上 对签名完的文件进行对齐处理
检查第三方lib合规性
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
|