androidsvg: Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed
I am getting the exception below occasionally when trying to execute the following code with compileSdkVersion 28
and Java 7. I am using com.caverock:androidsvg:1.2.1
.
GlideApp.with(context)
.as(PictureDrawable.class)
.listener(new SvgSoftwareLayerSetter())
.load("http://example.com/foo.svg")
.into(target);
public class SvgDrawableTranscoder implements ResourceTranscoder<SVG, PictureDrawable> {
@Nullable
@Override
public Resource<PictureDrawable> transcode(@NonNull Resource<SVG> toTranscode,
@NonNull Options options) {
SVG svg = toTranscode.get();
Picture picture = svg.renderToPicture();
PictureDrawable drawable = new PictureDrawable(picture);
return new SimpleResource<>(drawable);
}
}
public class SvgDecoder implements ResourceDecoder<InputStream, SVG> {
@Override
public boolean handles(@NonNull InputStream source, @NonNull Options options) {
return true;
}
public Resource<SVG> decode(@NonNull InputStream source, int width, int height,
@NonNull Options options)
throws IOException {
try {
SVG svg = SVG.getFromInputStream(source);
return new SimpleResource<>(svg);
} catch (SVGParseException ex) {
throw new IOException("Cannot load SVG from stream", ex);
}
}
}
@GlideModule
public class SvgModule extends AppGlideModule {
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide,
@NonNull Registry registry) {
registry.register(SVG.class, PictureDrawable.class, new SvgDrawableTranscoder())
.append(InputStream.class, SVG.class, new SvgDecoder());
}
// Disable manifest parsing to avoid adding similar modules twice.
@Override
public boolean isManifestParsingEnabled() {
return false;
}
}
Exception:
07-12 22:20:14.474 10798-10847/com.example.n1try.myapp E/GlideExecutor: Request threw uncaught throwable
java.lang.IllegalArgumentException: Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed
at android.graphics.Canvas.checkValidSaveFlags(Canvas.java:378)
at android.graphics.Canvas.saveLayerAlpha(Canvas.java:555)
at com.caverock.androidsvg.SVGAndroidRenderer.pushLayer(SVGAndroidRenderer.java:677)
at com.caverock.androidsvg.SVGAndroidRenderer.render(SVGAndroidRenderer.java:982)
at com.caverock.androidsvg.SVGAndroidRenderer.render(SVGAndroidRenderer.java:298)
at com.caverock.androidsvg.SVGAndroidRenderer.renderChildren(SVGAndroidRenderer.java:330)
at com.caverock.androidsvg.SVGAndroidRenderer.render(SVGAndroidRenderer.java:584)
at com.caverock.androidsvg.SVGAndroidRenderer.renderDocument(SVGAndroidRenderer.java:267)
at com.caverock.androidsvg.SVG.renderToPicture(SVG.java:306)
at com.caverock.androidsvg.SVG.renderToPicture(SVG.java:286)
at com.example.n1try.myapp.utils.svg.SvgDrawableTranscoder.transcode(SvgDrawableTranscoder.java:26)
at com.bumptech.glide.load.engine.DecodePath.decode(DecodePath.java:47)
at com.bumptech.glide.load.engine.LoadPath.loadWithExceptionList(LoadPath.java:58)
at com.bumptech.glide.load.engine.LoadPath.load(LoadPath.java:43)
at com.bumptech.glide.load.engine.DecodeJob.runLoadPath(DecodeJob.java:501)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromFetcher(DecodeJob.java:472)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromData(DecodeJob.java:458)
at com.bumptech.glide.load.engine.DecodeJob.decodeFromRetrievedData(DecodeJob.java:410)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherReady(DecodeJob.java:379)
at com.bumptech.glide.load.engine.DataCacheGenerator.onDataReady(DataCacheGenerator.java:95)
at com.bumptech.glide.load.model.FileLoader$FileFetcher.loadData(FileLoader.java:76)
at com.bumptech.glide.load.engine.DataCacheGenerator.startNext(DataCacheGenerator.java:75)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:302)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:269)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:233)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:446)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 19 (9 by maintainers)
Commits related to this issue
- Closes BigBadaboom/androidsvg#148: Invalid Layer Save Flag - only ALL_SAVE_FLAGS is allowed — committed to brudaswen/androidsvg by deleted user 6 years ago
- Issue #148: Added clipPath unit tests — committed to BigBadaboom/androidsvg by BigBadaboom 6 years ago
- Updated com.caverock:androidsvg to version 1.4. Resolves an issue of the library in SDK version 28. See https://github.com/BigBadaboom/androidsvg/issues/148 — committed to dbahat/conventions by dbahat 4 years ago
- Updated com.caverock:androidsvg to version 1.4. Resolves an issue of the library in SDK version 28. See https://github.com/BigBadaboom/androidsvg/issues/148 — committed to dbahat/conventions by dbahat 4 years ago
AndroidSVG uses the method
Canvas.save(int flags)
to implement clip path support on pre-Kit Kat devices. It was previously used for all versions of Android, but I created a new implementation for clip paths in v1.3 that uses APIs that are only available since Kit Kat.In Android 27 they deprecated the
Canvas.save(int flags)
method and most of the flag values. That was fair enough. The new versions of Skia (the underlying library that Android uses for 2D graphics), no longer support the version ofsave()
that take flags.Unfortunately, in Android 28, they seem to have taken the additional step of removing that
save()
method entirely. That means that the library cannot be compiled with compile/targetSdkVersion set to 28.If this doesn’t change, I will either have to:
If you want to help get Android to reverse their decision, please take the time to star the following bug ticket. And maybe add a supporting comment about how it would affect you if they don’t. Please be polite.
https://issuetracker.google.com/issues/110856542
In the meantime, you can migrate to the upcoming version 1.3 of AndroidSVG. Instructions on how you can use the snapshot release of 1.3 can be found on the 1.3 release notes page as @devemux86 said.
Thanks, Paul