Bazel 项目导入Android Studio编译,记录一次我的爬坑经历(思路)

933 阅读3分钟

最近要开发设备管理项目,除了看官方文档,阅读SDK源码以外,还找到了官方的一个样例测试项目。 android-testdpc 略微看了一下,涉及的功能点还不少,遂git clone下来打算自己跑来看一下。

没想到竟是我没接触过的Bazel项目,按照项目里readme文档说的下载AS的Bazel插件Bazel for Android Studio,然后在Android Studio中导入项目。

好吧,导入没成功,界面next点了根本没反应。 1719563998345.png

既然如此,何不直接转成Gradle编译项目?

说干就干。 咱也没怎么了解 Bazel,看了目录下几个没见过的文件

BUILD
setupcompat.BUILD
setupdesign.BUILD
WORKSPACE

BUILD 是 Bazel 项目的编译脚本,setupcompat 和 setupdesign 是我没接触过的东西,WORKSPACE 好像是项目的依赖库配置文件。

找到这下面的代码片段,都是依赖库,全部转成gradle的依赖方式。

maven_install(
    name = "maven",
    artifacts = [
        "androidx.annotation:annotation:1.5.0",
        "androidx.appcompat:appcompat:1.6.1",
        "androidx.appcompat:appcompat-resources:1.6.1",
        "androidx.collection:collection:1.2.0",
        "androidx.constraintlayout:constraintlayout:2.1.3",
        "androidx.core:core:1.6.0",
        "androidx.enterprise:enterprise-feedback:1.1.0",
        "androidx.legacy:legacy-support-core-ui:1.0.0",
        "androidx.legacy:legacy-support-v13:1.0.0",
        "androidx.lifecycle:lifecycle-common:2.5.1",
        "androidx.lifecycle:lifecycle-process:2.5.1",
        "androidx.lifecycle:lifecycle-runtime:2.5.1",
        "androidx.localbroadcastmanager:localbroadcastmanager:1.1.0",
        "androidx.preference:preference:1.1.0",
        "androidx.recyclerview:recyclerview:1.2.0",
        "androidx.test:core:1.5.0",
        "androidx.test:monitor:1.6.0",
        "androidx.test:runner:1.5.0",
        "androidx.window:window:1.2.0",
        "com.google.android.material:material:1.6.1",
        "com.google.guava:guava:31.1-android",
        "com.google.testparameterinjector:test-parameter-injector:1.15",
        "com.google.truth:truth:1.1.3",
        "com.google.errorprone:error_prone_annotations:2.26.1",
        "junit:junit:4.13.2",
        "javax.inject:javax.inject:1",
        "org.hamcrest:java-hamcrest:2.0.0.0",
        "org.robolectric:robolectric:4.9.2",
        "org.robolectric:robolectric-annotations:3.3.2",
        "org.robolectric:shadows-core:3.3.2",
        "org.bouncycastle:bcpkix-jdk15on:1.70",
        "org.bouncycastle:bcprov-jdk15on:1.70",
    ],
    repositories = [
        "https://maven.google.com",
        "https://repo1.maven.org/maven2",
    ],
    # for androidx.annotation 1.5.0. 1.6.0+ uses gradle module metadata
    # which rules_jvm_external cannot resolve yet, see
    # https://github.com/bazelbuild/rules_jvm_external/issues/909
    version_conflict_policy = "pinned",
)

包名在BUILD文件里有,copy到app的build.gradle中。

因为项目中有AIDL文件,配置开启一下

buildFeatures {
    aidl = true
}

settings.gradle中配置一下

include(":dpc")
project(":dpc").projectDir = File("../android-testdpc/")

尝试build一下,有点小激动,见证奇迹的时刻到了。。。没跑起来。

报错,提示build文件不是文件夹。看一下只有BUILD文件符合,居然不区分大小写和build文件夹冲突了,改成BUILD.bk

再build一下

又报错,提示有依赖包存在多个类重复

报错信息很直观,提示org.robolectric:robolectric-annotations:3.3.2org.robolectric:shadows-core:3.3.2依赖的多个库旧版本与org.robolectric:robolectric:4.9.2依赖的新版本冲突,可以用下面的配置解决

    configurations.all {
        exclude("org.robolectric", "shadow-api")
        exclude("org.robolectric", "robolectric-utils")
        exclude("org.robolectric", "shadows-core")
        exclude("org.robolectric", "robolectric-annotations")
    }

我直接干掉org.robolectric:robolectric-annotations:3.3.2org.robolectric:shadows-core:3.3.2的依赖,仅保留org.robolectric:robolectric:4.9.2

还有org.hamcrest:java-hamcrest:2.0.0.0和其他库中的依赖冲突,这回我直接配置排除依赖

    configurations.all {
        exclude("org.hamcrest", "hamcrest-core")
    }

再build一下,没有这些报错了,还差setupcompatsetupdesign这2个库的依赖。

看项目代码里,有 com.google.android.setupcompatcom.google.android.setupdesign包名导入,是代码库无疑了。

在WORKSPACE文件里找到了

http_archive(
    name = "setupdesign",
    build_file = "@//:setupdesign.BUILD",
    url = "https://android.googlesource.com/platform/external/setupdesign/+archive/4634dac90e3c09a78c2fcdfcb16ab9cb16265527.tar.gz",
)

http_archive(
    name = "setupcompat",
    build_file = "@//:setupcompat.BUILD",
    url = "https://android.googlesource.com/platform/external/setupcompat/+archive/2ce41c8f4de550b5186233cec0a722dd0ffd9a84.tar.gz",
)

居然是ASOP里面的代码模块。

这两个链接文件下载不了。

还好github还能访问,就到github上面找找碰一下运气。

还真给我找到了。

1719565705406.png

2个都有,各版本的都有。

git clone 把 这两个库的 android13-release 分支代码拉下来,配置成android library。里面已经配有build.gradle,但是不能直接用,编译SDK版本要改,minSdk至少16,setupcompat库中有AIDL文件要配置打开,一些依赖版本太低或缺失,build一下看报错信息就知道,逐一解决。

其中 有个错误提示矢量图宽高不能为0

Execution failed for task ':setupdesign:packageDebugResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$RunnableWrapperWorkAction
   > Error while processing D:\StudioProjects\android-testdpc\platform.external.setupdesign\main\res\drawable-anydpi-v21\sud_navbar_ic_back.xml : Width (0) and height (0) cannot be <= 0

对应文件

<vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:width="@dimen/sud_navbar_ic_intrinsic_size"
 android:height="@dimen/sud_navbar_ic_intrinsic_size"
 android:autoMirrored="true"
 android:tint="?attr/sudNavBarTextColor"
 android:viewportHeight="24"
 android:viewportWidth="24">

原因是dimen引用的值获取不到,为什么获取不到,不知道。直接改成对应的值24dp粗暴解决。

最后还有个问题,android-testdpc 代码里引用setupdesign库中R资源文件找不到,是项目编译配置关闭了R文件的传递(即library的R文件属性合并到app模块的R文件),在项目的gradle.properties中设置合并解决

android.nonTransitiveRClass=false

再build,编译成功。