将 gradle 构建工具从 3.6.1 升级到 4.1.0 时,特权应用程序的 dlopen 失败

dlopen failed for privileged app when upgrade gradle build tools from 3.6.1 to 4.1.0

我有一个位于 /system/priv-app/MyTestApp 的应用程序。 android源码环境为AndroidP(API28).

最初,MyTestApp.apk 是使用 gradle 构建工具 3.6.1 构建的。然后我将它升级到 4.1.0 并构建一个新的 MyTestApp.apk 并在 rom 中预构建它。所以崩溃发生了。

E AndroidRuntime: java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/priv-app/MyTestApp/MyTestApp.apk!/lib/armeabi-v7a/libmytest.so" not found
E AndroidRuntime:       at java.lang.Runtime.loadLibrary0(Runtime.java:1016)
E AndroidRuntime:       at java.lang.System.loadLibrary(System.java:1669)

我拉取文件/system/priv-app/MyTestApp/MyTestApp.apk,解压文件发现libmytest.so存在。这肯定是由 gradle 构建工具升级引起的。但是我找不到原因。有人可以帮忙吗?

查看源码后发现在bionic/linker/linker.cpp

if (entry.method != kCompressStored || (entry.offset % PAGE_SIZE) != 0) {
  close(fd);
  return -1;
}

entry.offset % PAGE_SIZE != 0 这个条件不成立。

所以我猜 AGP 4.1+ 的 zipalign 有问题。

仍在研究中。

Android 只要 属性 DONT_UNCOMPRESS_PRIV_APPS_DEXS 未定义,构建系统将为特权应用程序解压缩嵌入在 apk 中的 dex 文件。解压定义如下

# Uncompress dex files embedded in an apk.
#
define uncompress-dexs
$(hide) if (zipinfo $@ '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then \
  tmpdir=$@.tmpdir; \
  rm -rf $$tmpdir && mkdir $$tmpdir; \
  unzip -q $@ '*.dex' -d $$tmpdir && \
  zip -qd $@ '*.dex' && \
  ( cd $$tmpdir && find . -type f | sort | zip -qD -X -0 ../$(notdir $@) -@ ) && \
  rm -rf $$tmpdir; \
  fi
endef

使用AGP 4.0构建apk时,解压缩dexs后,可以通过zipalign工具验证成功。

zipalign -v -c -p 4 MyTestApp.apk

但是当使用 AGP 4.1+ (也包括 7.0-alpha) 构建时,它不能被 zipalign 工具验证。

但是我还没有找到原因。只是猜测 AGP 4.1+ 中的 apk 存档有一些新的变化。

android.useNewApkCreator=false

在gradle.properties中添加这一行可以解决这个问题。

但自 AGP 3.6+ 起,此 属性 的默认值为真。所以应该不是AGP 4.0和AGP 4.1的区别。

我很困惑。可能还有其他条件生效。

参考最新代码,uncompress-dexs方法如下

https://android.googlesource.com/platform/build/+/master/core/definitions.mk#2385

# Uncompress dex files embedded in an apk.
#
define uncompress-dexs
  if (zipinfo $@ '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then \
    $(ZIP2ZIP) -i $@ -o $@.tmp -0 "classes*.dex" && \
    mv -f $@.tmp $@ ; \
  fi
endef