: landoid /graphics/ColorSpace的分辨率失败



在我更新Android Studio到2020.3.1之前,它工作得很好。我刚刚发现Android .graphics. colorspace是在Android API 26中引入的。所有Android 8下的设备都会抛出这个异常。但是它怎么能通过编译呢?

Fatal Exception: java.lang.NoClassDefFoundError
Failed resolution of: Landroid/graphics/ColorSpace;
com.facebook.imageutils.ImageMetaData.getColorSpace (ImageMetaData.java:31)
com.facebook.imagepipeline.image.EncodedImage.readImageMetaData (EncodedImage.java:398)
com.facebook.imagepipeline.image.EncodedImage.internalParseMetaData (EncodedImage.java:363)
com.facebook.imagepipeline.image.EncodedImage.parseMetaData (EncodedImage.java:341)
com.facebook.imagepipeline.producers.NetworkFetchProducer.notifyConsumer (NetworkFetchProducer.java:187)
com.facebook.imagepipeline.producers.NetworkFetchProducer.maybeHandleIntermediateResult (NetworkFetchProducer.java:151)
com.facebook.imagepipeline.producers.NetworkFetchProducer.onResponse (NetworkFetchProducer.java:108)
com.facebook.imagepipeline.producers.NetworkFetchProducer$1.onResponse (NetworkFetchProducer.java:75)
com.facebook.imagepipeline.backends.okhttp3.OkHttpNetworkFetcher$2.onResponse (OkHttpNetworkFetcher.java:185)
okhttp3.internal.connection.RealCall$AsyncCall.run (RealCall.java:504)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1113)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:588)
java.lang.Thread.run (Thread.java:818)

这个异常是由这个方法抛出的。

private ImageMetaData readImageMetaData() {
InputStream inputStream = null;
ImageMetaData metaData = null;
try {
inputStream = getInputStream();
metaData = BitmapUtil.decodeDimensionsAndColorSpace(inputStream);
mColorSpace = metaData.getColorSpace();
Pair<Integer, Integer> dimensions = metaData.getDimensions();
if (dimensions != null) {
mWidth = dimensions.first;
mHeight = dimensions.second;
}
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
// Head in the sand
}
}
}
return metaData;
}

但是在这个方法中已经有一个ColorSpace的用法,并且在使用它之前确实检查了API级别。

public static ImageMetaData decodeDimensionsAndColorSpace(InputStream is) {
Preconditions.checkNotNull(is);
ByteBuffer byteBuffer = DECODE_BUFFERS.acquire();
if (byteBuffer == null) {
byteBuffer = ByteBuffer.allocate(DECODE_BUFFER_SIZE);
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
try {
options.inTempStorage = byteBuffer.array();
BitmapFactory.decodeStream(is, null, options);
ColorSpace colorSpace = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
colorSpace = options.outColorSpace;
}
return new ImageMetaData(options.outWidth, options.outHeight, colorSpace);
} finally {
DECODE_BUFFERS.release(byteBuffer);
}
}

这是我试过的。

  1. Gradle clean command.

  2. 构建→清洁项目。

  3. 构建→重建项目。

  4. buildToolsVersion更改为最新版本

  5. androidx.appcompat:appcompat更改为2.5.0。

  6. 添加multidex-config.txt和multidex-config.pro

但是这些都不起作用。

我的团队在将项目迁移到Gradle 7后遇到了同样的问题。我们开始看到致命的异常(java.lang.NoClassDefFoundError),说在com.facebook.imageutil . imagemetadata . getcolorspace (ImageMetaData.java:31) landoid/graphics/ColorSpace无法解析。喝了相当多的咖啡后,我们意识到应用程序只在发布配置中崩溃,这意味着它与proguard配置有关。猜测是正确的,下面的通配符规则修复了这个问题

-keep class com.facebook.** { *; }

但是我想把范围缩小到一个特定的类别。所以我开始挖掘usage.txt文件(由proguard生成的文件,与seeds.txt一起),这就是我得出的

-keep class com.facebook.imagepipeline.image.EncodedImage { *; }

我想知道这是否也会解决你所面临的问题。

问题出在这几行代码中。

ColorSpace colorSpace = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
colorSpace = options.outColorSpace;
}

当一个系统不支持特定的类时,你不能引用它的对象,但你仍然可以声明它。所以改成这个应该可以了。

ColorSpace colorSpace;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
colorSpace = options.outColorSpace;
}

你也需要调整return。把它放在if-else语句中。

return new ImageMetaData(options.outWidth, options.outHeight, colorSpace);