不用AS生成apk
大家应该经常能碰见这么一个场景,你的项目中有一个需求,要用一些第三方库,然后你就去网上搜,然后就github下了一大堆项目,用as一个个打开,一个个装到你的手机上。
是不是很麻烦??我也经常很烦,就想有没有什么可以直接打包的东西。
下面就介绍一下我不用AS生成apk的流程。本人行文相当口语化,嫌啰嗦的可以直接看最后的总结~
首先我先下载好项目工程,改改版本配置(gradle版本,support版本,sdk版本啥的,都习惯了,不喜欢各种版本都存在我的电脑上。。。。)
然后凭着记忆,在项目根目录启动cmd,输入
gradlew assembleRelease
然后控制台里就出现了一行字。。。
Downloading https://services.gradle.org/distributions/gradle-5.1.1-all.zip
我擦?什么情况? 赶紧使用“复制”终止命令行。(ctrl+c 在cmd中是中断当前操作,真正的复制是,你选中目标字符串,然后华丽丽的轻敲一下回车车键~~)
额。。。我明明下载过gradle。。。为啥又让我重新下载??
因为我改过gradle默认目录,然后去C盘一看,果然里面有下载残留。
嗯。。如何让他使用我下载过的gradle包呢?
经过一番baidu,得知他会检查项目中的/gradle/wrapper/gradle-wrapper.properties文件,下载其中distributionUrl对应的字段。
把之前下载过的zip包,放到/gradle/wrapper/目录下,然后将distributionUrl字段改成zip包的名字gradle-5.1.1-all.zip,先执行一个小命令试一下。
gradlew -v
又出现了下面的文字
Downloading
file:/D:/develop/AS-workspace/**/gradle/wrapper/gradle-5.1.1-all.zip
…
Unzipping
C:\Users\USER-PC.gradle\wrapper\dists\gradle-5.1.1-all\8mirmttuugrzl5l1j9b5p0az9\gradle-5.1.1-all.zip to C:\Users\USER-PC.gradle\wrapper\dists\gradle-5.1.1-all\8mirmttuugrzl5l1j9b5p0az9
嗯。。。倒是不下载了,解压又解压进了C盘。不行!C盘这么神圣的地方,绝对不允许侵占!!
是不是什么环境变量或者参数中配置了C盘的默认目录??
查了一下项目跟目录的gradlew和gradlew.bat文件,在gradlew.bat文件中发现了这样一行代码
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
看你不像一段正经代码,果断查看此jar!
果然!发现其中有这么一个文件
public class GradleUserHomeLookup
{
public static final String DEFAULT_GRADLE_USER_HOME = System.getProperty("user.home") + "/.gradle";
public static final String GRADLE_USER_HOME_PROPERTY_KEY = "gradle.user.home";
public static final String GRADLE_USER_HOME_ENV_KEY = "GRADLE_USER_HOME";
public static File gradleUserHome()
{
String gradleUserHome;
if ((gradleUserHome = System.getProperty("gradle.user.home")) != null) {
return new File(gradleUserHome);
}
if ((gradleUserHome = System.getenv("GRADLE_USER_HOME")) != null) {
return new File(gradleUserHome);
}
return new File(DEFAULT_GRADLE_USER_HOME);
}
}
嘿,让我找到了,大意就是定义gradleUserHome文件,gradle.user.home和GRADLE_USER_HOME我猜应该是定义的环境变量和配置参数,我这两个都没设置过,那就是DEFAULT_GRADLE_USER_HOME = System.getProperty(“user.home”) + “/.gradle”;这个了。人赃俱获!没毛病!
把/gradle/wrapper/gradle-wrapper.properties中的 distributionBase和zipStoreBase改成"…/…/"试试(相对目录,指向项目根目录),再次执行gradlew命令,又出现了以下错误。
Exception in thread “main” java.lang.RuntimeException: Base: …/…/ is unknown
at org.gradle.wrapper.PathAssembler.getBaseDir(PathAssembler.java:97)
at org.gradle.wrapper.PathAssembler.getDistribution(PathAssembler.java:43)
at org.gradle.wrapper.Install.createDist(Install.java:44)
at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:107)
at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:61)
哎嗨,这太熟悉了,一秒钟定位到PathAssembler.java:97
public class PathAssembler {
...
private File getBaseDir(String base) {
if (base.equals("GRADLE_USER_HOME"))
return this.gradleUserHome;
if (base.equals("PROJECT")) {
return new File(System.getProperty("user.dir"));
}
throw new RuntimeException("Base: " + base + " is unknown");
}
...
}
哦。。原来已经帮我们定义好了一个常量PROJECT,很人性化嘛~
继续将distributionBase和zipStoreBase改成PROJECT,再再次执行gradlew命令。
终于出现了正常的信息,然后执行编译命令
gradlew assembleRelease
啊哈。。电影中黑客的镜头来了,控制台中源源不断地输出信息。。。
等他扑棱完了,一看,what????FAILED???
Starting a Gradle Daemon (subsequent builds will be faster)
FAILURE: Build failed with an exception.
- What went wrong: A problem occurred configuring project ‘:app’.
SDK location not found. Define location with an ANDROID_SDK_ROOT environment variable or by setting the sdk.dir path in your project’s
local properties file at
‘D:\develop\AS-workspace**\local.properties’.- Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
- Get more help at https://help.gradle.org
BUILD FAILED in 1m 5s
哦。。。原来是太兴奋,忘了配置local.properties。
从别的项目copy一份过来,继续编译。
额。。。又出错了。。
- What went wrong: Execution failed for task ‘:commonsdk:verifyReleaseResources’.
1 exception was raised by workers: com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource
linking failed
D:\develop\AS-workspace**\build\intermediates\res\merged\release\layout\card_item_picture.xml:11:
error: attribute cardCornerRadius (aka
com..:cardCornerRadius) not found.
D:\develop\AS-workspace*\commonsdk\build\intermediates\res\merged\release\layout\card_item_picture.xml:11:
error: attribute cardElevation (aka com..:cardElevation)
not found.
D:\develop\AS-workspace***\build\intermediates\res\merged\release\layout\card_item_picture.xml:11:
error: attribute cardPreventCornerOverlap (aka
com..:cardPreventCornerOverlap) not found. error: failed
linking file resources.
找不到attribute??这个貌似必须打开as才行了。。。
我打开as后,也没发现这个地方有错误啊。。突然间暼到一行字
22:06 Executing tasks: [:app:assembleDebug]
恍然大悟啊。。。重新执行命令:
gradlew app:assembleRelease
哎嗨。终于成功了!!
等会,怎么是app-release-unsigned.apk???
手动添加signingConfig signingConfigs.release
再次执行命令。。。。。。。。。。。。。。
喜大普奔啊~~
难道release不自带signingConfig signingConfigs.release属性????
最后总结一下:
\gradle\wrapper\gradle-wrapper.properties
# distributionBase=GRADLE_USER_HOME
distributionPath=gradle/wrapper/dists
# zipStoreBase=GRADLE_USER_HOME
zipStorePath=gradle/wrapper/dists
#下面两句 决定下载和解压环境 PROJECT为项目目录
distributionBase=PROJECT
zipStoreBase=PROJECT
# 默认路径是/gradle/wrapper/ 提前将zip包放到对应目录 可以指定其他本地路径
distributionUrl=gradle-5.1.1-all.zip
app(主module)的build.gradle
buildTypes {
release {
//添加签名信息
signingConfig signingConfigs.debug
}
}
- 想要不重新下载gradle包,
1).先将之前的zip放到/gradle/wrapper目录下
2).然后配置gradle-wrapper.properties中的distributionUrl=gradle-5.1.1-all.zip - 想要不污染C盘
1) 配置gradle-wrapper.properties
distributionBase=PROJECT
zipStoreBase=PROJECT - 如果你的gradle仓库目录没有改,自然也就不会出现上面的问题
- 即使你配置了第一步、第二部,C盘依然会生成一些缓存文件,哈哈哈哈哈哈
- 记得添加 local.properties
- 编译要使用app:assembleRelease,要不然编译的时候可能会找不到module之间的依赖关系。app当然是你主module的名字
- 要显式的声明signingConfig signingConfigs.release(可是我记得是默认的啊。。。)
- apk的输出依然是build的目录里面。
- 网上的东西绝大多数都是抄来抄去,尽信百度则不如无百度。要有自主分辨的能力,也要有知其然知其所以然的意志。