Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

安卓自动化之旅(四)——尝试使用Docker环境来构建APK 下 #69

Open
soapgu opened this issue Aug 9, 2021 · 0 comments
Labels
安卓 安卓

Comments

@soapgu
Copy link
Owner

soapgu commented Aug 9, 2021

  • 引言

接着上回未完的博客,一定要把革命进行到底。上回Android SDK没有安装造成编译apk失败。所以首先要把工作内容回到Android SDK的安装。

  • Linux环境安装Android SDK

  • 脱离Android Studio的Command line tools only
    我们已经太习惯了Android Studio这个IDE了,现在技术已经逐渐成熟,是时候脱离拐杖自己走路了。

sdkmanager 是一个命令行工具,您可以用它来查看、安装、更新和卸载 Android SDK 的软件包。如果您使用 Android Studio,则无需使用此工具,而可以从 IDE 管理 SDK 软件包。

sdkmanager 工具在 Android SDK Tools 软件包(25.2.3 及更高版本)中提供,并位于 android_sdk/tools/bin/ 下。

  1. 下载完成后拷贝到 android_sdk目录下
  2. 运行android-sdk/cmdline-tools/bin下的sdkmanager
  3. sdkmanager --list 找到要下载的包,分别是platforms;android-30,build-tools;30.0.3

基本思路确定好。改写Dockerfile

FROM openjdk:11.0.2-jre-stretch AS base

RUN mkdir /andriod
WORKDIR /andriod
ADD . /andriod
RUN chmod +x ./gradlew

# 拷贝android tools到容器中
#COPY commandlinetools-linux-7583922_latest.zip /andriod
# 解压android tools
RUN mkdir -p /opt/app/android-sdk
RUN unzip -d /opt/app/android-sdk commandlinetools-linux-7583922_latest.zip

ENV ANDROID_SDK_ROOT /opt/app/android-sdk
ENV PATH /opt/app/android-sdk/cmdline-tools/bin:$PATH

RUN ls /opt/app/android-sdk

WORKDIR /opt/app/android-sdk/cmdline-tools/bin
#RUN chmod +x ./sdkmanager
#RUN sdkmanager --list  --sdk_root=$ANDROID_SDK_ROOT

RUN yes | sdkmanager "platforms;android-30" --sdk_root=$ANDROID_SDK_ROOT
RUN yes | sdkmanager "build-tools;30.0.3" --sdk_root=$ANDROID_SDK_ROOT

WORKDIR /andriod
RUN ./gradlew tasks

脚本解析

  1. 本地下载好Command line tools的zip放到打包文件夹里面
  2. 建好/opt/app/android-sdk并把这个目录设为ANDROID_SDK_ROOT环境变量,很重要这样项目里面就不用配置local.properties文件了
  3. 把/opt/app/android-sdk/cmdline-tools/bin加到PATH变量里面去
  4. 分别安装"platforms;android-30","build-tools;30.0.3"两个包
  • 编译Docker Image

docker build --progress=plain -t soapgu/androiddockertest:v1.0 .
  1. 这里--progress=plain非常有用,可以吧中间过程很清晰的打印出来,方便调试
  2. docker的build cache确实好用,由于是中间有网络过程,不是一定成功的,只要Dockerfile没有修改过。即使失败了,前面的Step也保存下来了。就和游戏里面Save&Load一样。节约一定效率
  • 用编译完成的Docker Image来编译APK

docker run -it -v "D:\dockerbuilds:/andriod/app/build" soapgu/androiddockertest:v1.0 ./gradlew assembleDebug

这里把打包apk的输出目录映射到本地

PS D:\WorkSpace\PlayPen\DockerBuildApk> docker run -it -v "D:\dockerbuilds:/andriod/app/build" soapgu/androiddockertest:v1.0 ./gradlew assembleDebug
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could not be reused, use --status for details
Checking the license for package Android SDK Build-Tools 30.0.2 in /opt/app/android-sdk/licenses
License for package Android SDK Build-Tools 30.0.2 accepted.
Preparing "Install Android SDK Build-Tools 30.0.2 (revision: 30.0.2)".
"Install Android SDK Build-Tools 30.0.2 (revision: 30.0.2)" ready.
Installing Android SDK Build-Tools 30.0.2 in /opt/app/android-sdk/build-tools/30.0.2
"Install Android SDK Build-Tools 30.0.2 (revision: 30.0.2)" complete.
"Install Android SDK Build-Tools 30.0.2 (revision: 30.0.2)" finished.

Deprecated Gradle features were used in this build, making it incompatible with Gradle 8.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/7.0.2/userguide/command_line_interface.html#sec:command_line_warnings

BUILD SUCCESSFUL in 1m 58s
27 actionable tasks: 27 executed

终于成功了,可以看到apk了
图片

  • 验证APK

连上安卓手机

PS D:\dockerbuilds\outputs\apk\debug> adb devices
List of devices attached
47DDU20A10008976        device

PS D:\dockerbuilds\outputs\apk\debug> adb install .\app-debug.apk
Performing Streamed Install
Success

图片

  • 中间碰到的问题

前面你看到的都是比较流畅的完整流程。实际过程远远没这么顺利,前前后后差不多花了两天时间。一方面我Docker的水平确实是渣渣。

  • 问题一:弄坏PATH环境变量
    这个问题一开始就存在了,设了cmdline-tools/bin的PATH,注意PATH是要merge进去的而不是设置进去的。这个结果造成后面所有的Linux命令都不能用了,吐血啊。后来排查好久才发现的问题。一个很愚蠢的低级失误。

  • 问题二:sdkmanager 命令必须要设置sdk_root变量
    这条其实比较好找,报错信息也比较清晰,不难对付

  • 问题三:docker里面加了slim前缀究竟有啥用?
    这个其实是实践过程中的问题,加了slim的tag好像同比大小小一点。用了之后果然小有小的道理,unzip不能用,如果用slim版本还要自己写脚本装,算了偷个懒还是算了吧。

  • 问题四:似懂非懂的JAVA版本
    这个问题也造成我非常多的困扰和主要的消耗时间。本来胜利就在眼前,结果build直接出一个错。深不见底的堆栈里也看不出头绪,是个非常底层的JAVA堆栈报错。搜了一圈资料,有指出是JAVA版本问题。

PS D:\WorkSpace\PlayPen\DockerBuildApk> java -version
openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189)
OpenJDK 64-Bit Server VM (build 11.0.10+0-b96-7249189, mixed mode)

这是本机的JAVA环境,编译完全没有问题
我原来的环境是 openjdk:11.0.10-jre-buster
再对一下JAVA 的version

PS D:\dockerbuilds\outputs\apk\debug> docker run -it  openjdk:11.0.10-jre-buster /bin/bash
Unable to find image 'openjdk:11.0.10-jre-buster' locally
11.0.10-jre-buster: Pulling from library/openjdk
bd8f6a7501cc: Already exists
44718e6d535d: Already exists
efe9738af0cb: Already exists
c647a8e650d3: Already exists
cf7f1fadeec3: Already exists
f9fb8b5acc3c: Already exists
Digest: sha256:60fc7f8d1deb9672df29785cab71a7ecc37949de870018063c6f5a4ee485bc51
Status: Downloaded newer image for openjdk:11.0.10-jre-buster
root@f96f60db3318:/# java -version
openjdk version "11.0.10" 2021-01-19
OpenJDK Runtime Environment 18.9 (build 11.0.10+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.10+9, mixed mode, sharing)
  • OpenJDK Runtime Environment (build 11.0.10+0-b96-7249189) != OpenJDK Runtime Environment 18.9 (build 11.0.10+9)

  • OpenJDK 64-Bit Server VM (build 11.0.10+0-b96-7249189, mixed mode) != OpenJDK 64-Bit Server VM 18.9 (build 11.0.10+9, mixed mode, sharing)
    后面两行不同
    尝试换到JAVA8,后面两行是一样了,gradle7又不能用了,一定要JAVA11,昏过去。
    最后找下老一点的镜像 openjdk:11.0.2-jre-stretch,总算是JAVA11,后面两行一致,编译通过。里面的道道还没摸透。还需要进一步深入。

  • 经验总结

  1. docker build 带上 --progress=plain对调试帮助很大
  2. docker run -it [image] /bin/bash , 调试docker帮助很大
  3. JAVA 的version其实博大精深,是个深坑
  4. 编译APK看上去是个简单不能简单的活,感觉和证明1+1=2一样。其实藏了这么多细节和经验。基础知识不能放松,脱离了IDE感觉就变成了残废。虽然遇到很多问题,但是从底层再摸一遍还是很有收获了。
    先到这里,其实后面还有很多要完善的细节
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
安卓 安卓
Projects
None yet
Development

No branches or pull requests

1 participant