penfeizhou / apng4android Goto Github PK
View Code? Open in Web Editor NEWAndroid animation support for APNG & Animated WebP & Gif & Animated AVIF, High performance
License: Apache License 2.0
Android animation support for APNG & Animated WebP & Gif & Animated AVIF, High performance
License: Apache License 2.0
播放动画有时候会卡顿,是什么原因?
I'd like to process something when it's specific index.
I have a lot of these messages in log. Is it a misconfiguration on my end?
2019-08-03 11:59:11.248 26871-26871/app.fedilab.android I/FrameSeqDecoder: No need to stop
2019-08-03 11:59:11.251 26871-27830/app.fedilab.android I/FrameSeqDecoder: Set state to RUNNING,cost 3
I needed to change my code, now I use the lib like this:
Glide.with(context)
.asFile()
.load(emoji.getUrl())
.into(new SimpleTarget<File>() {
@Override
public void onResourceReady(@NonNull File resourceFile, @Nullable Transition<? super File> transition) {
Drawable resource;
if( emoji.getUrl().endsWith(".gif")){
resource = GifDrawable.fromFile(resourceFile.getAbsolutePath());
((GifDrawable) resource).start();
}else{
resource = APNGDrawable.fromFile(resourceFile.getAbsolutePath());
}
final String targetedEmoji = ":" + emoji.getShortcode() + ":";
if (contentSpan != null && contentSpan.toString().contains(targetedEmoji)) {
//emojis can be used several times so we have to loop
for (int startPosition = -1; (startPosition = contentSpan.toString().indexOf(targetedEmoji, startPosition + 1)) != -1; startPosition++) {
final int endPosition = startPosition + targetedEmoji.length();
if( endPosition <= contentSpan.toString().length() && endPosition >= startPosition) {
ImageSpan imageSpan;
if( !disableAnimatedEmoji) {
resource.setBounds(0, 0, (int) Helper.convertDpToPixel(20, context), (int) Helper.convertDpToPixel(20, context));
resource.setVisible(true, true);
imageSpan = new ImageSpan(resource);
}else{
resource.setVisible(true, true);
Bitmap bitmap = drawableToBitmap(resource.getCurrent());
imageSpan = new ImageSpan(context,
Bitmap.createScaledBitmap(bitmap, (int) Helper.convertDpToPixel(20, context),
(int) Helper.convertDpToPixel(20, context), false));
}
contentSpan.setSpan(
imageSpan, startPosition,
endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
}
}
});
调用代码如下:
Glide.with(this)
.load("$rootDir/animPic/microphone.png")
.listener(object : RequestListener {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean {
return false
}
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
if (resource is APNGDrawable) {
resource.setLoopLimit(0)
}
return false
}
})
.into(ivMicrophone)
Info | Value | |
---|---|---|
Device Info | (1) Huawei Honor 8X + (2) Android emu API29 | |
System Version | (1) 9.0 + (2) 10.0 | |
APNG4Android Library Version | 1.3.3 | |
Repro rate | all the time (100%) | |
Repro with our demo project | not tried | |
Demo project link | N/A |
When trying to use the library's FileLoader
, my images wouldn't be displayed when passing absolute paths located on the SD card. I guess that is because APNG4Android relies on File
only, and not on SAF.
To fix that, I implemented a custom StreamLoader
that fetches the proper InputStream
(see below).
The problem is, APNG4Android seems to call InputStream
's reset
method without intercepting the IOException
, resulting in an empty image.
NB : The problem does not come from the test image I use, because it is properly displayed and animated when located in the phone's memory (the area where new FileInputStream(file)
works fine).
// FileLoader loader = new FileLoader(absolutePath): <-- doesn't work when absolutePath points to a location on the SD card
ImgLoader loader = new ImgLoader(absolutePath);
APNGDrawable apngDrawable = new APNGDrawable(loader);
imgView.setImageDrawable(apngDrawable);
// Load the image using an InputStream whatever the location of the path (phone memory or SD card)
static class ImgLoader extends StreamLoader {
private String path;
ImgLoader(String path) {
this.path= path;
}
@Override
protected InputStream getInputStream() throws IOException {
DocumentFile file = FileHelper.getDocumentFile(new File(path), false); // Helper to get a DocumentFile out of the given File
if (null == file || !file.exists()) return null; // Not triggered
return App.getInstance().getContentResolver().openInputStream(file.getUri());
}
}
Suggestions
a. Catch the reported exception (see below) and continue loading the image properly
and/or
b. Use ContentResolver.openInputStream
inside FileReader
to support resources located on SAF area.
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: java.io.IOException: mark/reset not supported
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at java.io.InputStream.reset(InputStream.java:348)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at java.io.FilterInputStream.reset(FilterInputStream.java:226)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.io.StreamReader.reset(StreamReader.java:39)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.io.FilterReader.reset(FilterReader.java:30)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGFrame.encode(APNGFrame.java:89)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw(APNGFrame.java:126)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw(APNGFrame.java:22)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGDecoder.renderFrame(APNGDecoder.java:190)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.decode.FrameSeqDecoder.step(FrameSeqDecoder.java:451)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.decode.FrameSeqDecoder.access$200(FrameSeqDecoder.java:34)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at com.github.penfeizhou.animation.decode.FrameSeqDecoder$1.run(FrameSeqDecoder.java:58)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at android.os.Handler.handleCallback(Handler.java:883)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at android.os.Handler.dispatchMessage(Handler.java:100)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at android.os.Looper.loop(Looper.java:214)
2020-02-23 22:30:02.900 7395-7559/app.debug W/System.err: at android.os.HandlerThread.run(HandlerThread.java:67)
1.很感谢你的库。
2.使用FileLoader加载apng文件,出现内存以0.2M/s的速度在增加,然后加载到一定大小又回回到原内存,请问这种情况是什么原因?是否正常?
能不能加载网络webp资源,加载本地的webp资源时透明部分会变为白色
Originally posted by @sun55 in #39 (comment)
ANR Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 22. Wait queue head age: 5506.6ms.)
线上出现大量:
Caused by: com.github.penfeizhou.animation.apng.decode.APNGParser$FormatException: APNG Format error
at com.github.penfeizhou.animation.apng.decode.APNGParser.parse(APNGParser.java)
at com.github.penfeizhou.animation.apng.decode.APNGDecoder.read(APNGDecoder.java)
at com.github.penfeizhou.animation.apng.decode.APNGDecoder.read(APNGDecoder.java)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder$2.call(FrameSeqDecoder.java)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder$2.call(FrameSeqDecoder.java)
Android版本均有分布,机型也均有分布。
我是使用OKhttp下载到本地后,使用此框架加载的。
如何停止播放后,停留在第一帧呢?
com.github.penfeizhou.android.animation:glide-plugin:1.0.0
Glide.with(imageView)
.load("https://misc.aotu.io/ONE-SUNDAY/SteamEngine.png")
.into(imageView);
How can I register the Animatable2Compat.AnimationCallback
to Glide?
I want to get the callback on animation start and end.
I am using your library with my application and I am pretty happy with it. Recently, FDroid build failed due to the dependency to https://dl.bintray.com/osborn/Android
What would be the best way to remove this dependency? Thanks for helping
Loading APNG doesn't show an animated image.
Trying to load APNG into an ImageView using the following code
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Glide
.with(this)
.load("https://misc.aotu.io/ONE-SUNDAY/SteamEngine.png")
.into(img)
}
}
With the following dependencies
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.penfeizhou.android.animation:glide-plugin:2.0.0'
Image is loaded but it is not moving, I tried the one with WebP https://isparta.github.io/compare-webp/image/gif_webp/webp/2.webp
and it is working perfectly.
Device tested on:
Emulator: Nexus 5 API 28
minSdkVersion: 26
targetSdkVersion: 30
Also used this Image, still same result
I would be happy to support more info
Any idea why is this happening?
I have an issue with animated emoji in a GridView using ArrayAdapter. It's lagging and I got a lot of messages: E/FrameSeqDecoder: Processing,wait for finish at INITIALIZING
Here is my adapter:
public class CustomEmojiAdapter extends ArrayAdapter<Emojis> {
private Context context;
private List<Emojis> emojis;
public CustomEmojiAdapter(@NonNull Context context, int resource, List<Emojis> emojis) {
super(context, resource, resource);
this.context = context;
this.emojis = emojis;
}
@Override
public int getCount() {
return emojis.size();
}
@Override
public Emojis getItem(int position) {
return emojis.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@NonNull
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
final ImageView imageView;
Emojis emoji = emojis.get(position);
if (convertView == null) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
convertView = layoutInflater.inflate(R.layout.drawer_emoji_picker, parent, false);
imageView = convertView.findViewById(R.id.img_custom_emoji);
} else {
imageView = (ImageView) convertView;
}
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean disableAnimatedEmoji = sharedpreferences.getBoolean(Helper.SET_DISABLE_ANIMATED_EMOJI, false);
Glide.with(context)
.asFile()
.load(emoji.getUrl())
.listener(new RequestListener<File>() {
@Override
public boolean onResourceReady(File resource, Object model, Target<File> target, DataSource dataSource, boolean isFirstResource) {
return false;
}
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
return false;
}
})
.into(new SimpleTarget<File>() {
@Override
public void onResourceReady(@NonNull File resourceFile, @Nullable Transition<? super File> transition) {
Drawable resource;
if(GifParser.isGif(resourceFile.getAbsolutePath())){
resource = GifDrawable.fromFile(resourceFile.getAbsolutePath());
}else{
resource = APNGDrawable.fromFile(resourceFile.getAbsolutePath());
}
if( !disableAnimatedEmoji) {
resource.setVisible(true, true);
imageView.setImageDrawable(resource);
}else{
Bitmap bitmap = drawableToBitmap(resource.getCurrent());
imageView.setImageBitmap(bitmap);
}
}
});
return convertView;
}
}
I can't use the plugin for Glide but it worked perfectly simply with:
Glide.with(context)
.load(emoji.getUrl())
.into(imageView);
Thanks for helping
Hey,
I wonder if the library could accept a lower minSdkVersion currently set to 19?
12-04 20:48:21.560 E/AndroidRuntime(10899): FATAL EXCEPTION: FrameDecoderExecutor-1 12-04 20:48:21.560 E/AndroidRuntime(10899): Process: com.xxx.xxx, PID: 10899 12-04 20:48:21.560 E/AndroidRuntime(10899): java.lang.IllegalStateException: copyPixelsFromBuffer called on recycled bitmap 12-04 20:48:21.560 E/AndroidRuntime(10899): at android.graphics.Bitmap.checkRecycled(Bitmap.java:383) 12-04 20:48:21.560 E/AndroidRuntime(10899): at android.graphics.Bitmap.copyPixelsFromBuffer(Bitmap.java:549) 12-04 20:48:21.560 E/AndroidRuntime(10899): at com.github.penfeizhou.animation.FrameAnimationDrawable.onRender(FrameAnimationDrawable.java:11) 12-04 20:48:21.560 E/AndroidRuntime(10899): at com.github.penfeizhou.animation.decode.FrameSeqDecoder$1.run(FrameSeqDecoder.java:7) 12-04 20:48:21.560 E/AndroidRuntime(10899): at android.os.Handler.handleCallback(Handler.java:751) 12-04 20:48:21.560 E/AndroidRuntime(10899): at android.os.Handler.dispatchMessage(Handler.java:95) 12-04 20:48:21.560 E/AndroidRuntime(10899): at android.os.Looper.loop(Looper.java:154) 12-04 20:48:21.560 E/AndroidRuntime(10899): at android.os.HandlerThread.run(HandlerThread.java:61)
Does the Glide support change the general behaviour (or is it a change in Glide 4.9.0)? I will explain my issue.
I was using Glide in that way for loading some profile pictures:
Glide.with(imageView.getContext())
.load(url)
.apply(new RequestOptions().transforms(new CenterCrop(), new RoundedCorners(10)))
.into(imageView);
When it was a gif URL, that worked but now I get a message telling me it can't load a gif image as a bitmap.
My current fix is:
if ( url.endsWith(".gif")) {
try {
Glide.with(imageView.getContext())
.asGif()
.load(url)
.apply(new RequestOptions().transforms(new CenterCrop(), new RoundedCorners(10)))
.into(imageView);
} catch (Exception ignored) {
}
} else {
try {
Glide.with(context)
.asBitmap()
.apply(new RequestOptions().transforms(new CenterCrop(), new RoundedCorners(10)))
.load(urlStatic)
.into(imageView);
} catch (Exception ignored) {
}
}
Info | Value | |
---|---|---|
Device Info | e.g. Huawei Mate 30 pro | |
System Version | e.g. 6.0 | |
APNG4Android Library Version | e.g. 1.0.0 | |
Repro rate | e.g. all the time (100%) / sometimes x% / only once | |
Repro with our demo project | e.g. does it happen with our demo project? | |
Demo project link | e.g. link to a demo project that highlights the issue |
Please fill in the detailed description of the issue (full output of any stack trace, compiler error, ...) and the steps to reproduce the issue.
会报 class file for androidx.core.view.NestedScrollingChild3 not found 错误
这是个啥?
compileSdkVersion = 29
buildToolsVersion = "29.0.2"
com.android.tools.build:gradle:4.0.1
androidx.recyclerview:recyclerview:1.1.0
androidx.appcompat:appcompat:1.1.0
androidx.viewpager2:viewpager2:1.0.0
Info | Value | |
---|---|---|
Device Info | Huawei P8 lite 2017 (HWPRA-H) | |
System Version | Android 8.0 | |
APNG4Android Library Version | 1.3.3 |
I only see that error logs and I can't link the call from my project that throws them.
java.lang.OutOfMemoryError:
at java.nio.HeapByteBuffer.<init> (HeapByteBuffer.java:54)
at java.nio.HeapByteBuffer.<init> (HeapByteBuffer.java:49)
at java.nio.ByteBuffer.allocate (ByteBuffer.java:261)
at com.github.penfeizhou.animation.io.ByteBufferWriter.reset (ByteBufferWriter.java:51)
at com.github.penfeizhou.animation.apng.io.APNGWriter.reset (APNGWriter.java:33)
at com.github.penfeizhou.animation.apng.decode.APNGFrame.encode (APNGFrame.java:70)
at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw (APNGFrame.java:126)
at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw (APNGFrame.java:22)
at com.github.penfeizhou.animation.apng.decode.APNGDecoder.renderFrame (APNGDecoder.java:190)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.step (FrameSeqDecoder.java:451)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.access$200 (FrameSeqDecoder.java:34)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder$1.run (FrameSeqDecoder.java:58)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.innerStart (FrameSeqDecoder.java:270)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.access$900 (FrameSeqDecoder.java:34)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder$3.run (FrameSeqDecoder.java:240)
at android.os.Handler.handleCallback (Handler.java:808)
at android.os.Handler.dispatchMessage (Handler.java:101)
at android.os.Looper.loop (Looper.java:166)
at android.os.HandlerThread.run (HandlerThread.java:65)
Info | Value | |
---|---|---|
Device Info | e.g. Huawei Mate 30 pro | |
System Version | e.g. 6.0 | |
APNG4Android Library Version | e.g. 1.0.0 | |
Repro rate | e.g. all the time (100%) / sometimes x% / only once | |
Repro with our demo project | e.g. does it happen with our demo project? | |
Demo project link | e.g. link to a demo project that highlights the issue |
Please fill in the detailed description of the issue (full output of any stack trace, compiler error, ...) and the steps to reproduce the issue.
Can I use your library to check the source is APNG or not?
写了个demo RecyclerView中用glide加载apng 多个item同时加载会卡死UI
Hello!
I saw your library and I really like it.
It is the only library I found that handles animated webp, but unfortunately I couldn't make it work.
I tried both:
final byte[] ret = WebPEncoder.fromGif(new AssetStreamLoader(context, "test.gif")).build();
File file = new File(context.getCacheDir(), "test.webp");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(ret);
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
and
WebPEncoder encoder = new WebPEncoder();
int duration = 0;
for (int i = 0; i < standardGifDecoder.getFrameCount(); i++) {
Bitmap bitmap = standardGifDecoder.getNextFrame();
encoder.addFrame(bitmap, 0,0, standardGifDecoder.getNextDelay());
}
But both gave me an invalid webp file (attaching it).
test1.zip
It would be amazing if you could help me, or even direct me to the bug so I can open a PR.
Thanks!
这边遇到了一种情况
有时FrameAnimationDrawable的onRender方法调用时frameSeqDecoder.getSampleSize()返回的是1
接着frameSeqDecoder的setDesiredSize调用,然后sampleSize就变成2了
再往后的onRender方法里,给过来的byteBuffer就小了,但是bitmap已经创建了,还是原来的大小所以
if (byteBuffer.remaining() < this.bitmap.getByteCount()) {
Log.e(TAG, "onRender:Buffer not large enough for pixels");
return;
}
这个条件就一直是true了,就一直报这个错误了
Originally posted by @ffts in #55 (comment)
和你讨论下库导致内存递增的问题
APNG的库代码混淆有要注意的吗?
相同的apng链接 下拉刷新重复加载后 apng播放速度越来越快
Info | Value | |
---|---|---|
Device Info | e.g. Huawei Mate 30 pro | |
System Version | e.g. 6.0 | |
APNG4Android Library Version | e.g. 1.0.0 | |
Repro rate | e.g. all the time (100%) / sometimes x% / only once | |
Repro with our demo project | e.g. does it happen with our demo project? | |
Demo project link | e.g. link to a demo project that highlights the issue |
Please fill in the detailed description of the issue (full output of any stack trace, compiler error, ...) and the steps to reproduce the issue.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Rect.width()' on a null object reference at com.github.penfeizhou.animation.FrameAnimationDrawable.getIntrinsicWidth(FrameAnimationDrawable.java:196) at android.widget.ImageView.invalidateDrawable(ImageView.java:293) at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:450) at android.graphics.drawable.Drawable.setVisible(Drawable.java:859) at com.github.penfeizhou.animation.FrameAnimationDrawable.setVisible(FrameAnimationDrawable.java:191) at android.widget.ImageView.updateDrawable(ImageView.java:1061) at android.widget.ImageView.setImageDrawable(ImageView.java:609) at com.bumptech.glide.request.target.DrawableImageViewTarget.setResource(DrawableImageViewTarget.java:28) at com.bumptech.glide.request.target.DrawableImageViewTarget.setResource(DrawableImageViewTarget.java:10) at com.bumptech.glide.request.target.ImageViewTarget.setResourceInternal(ImageViewTarget.java:127) at com.bumptech.glide.request.target.ImageViewTarget.onResourceReady(ImageViewTarget.java:104) at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:582) at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:544) at com.bumptech.glide.load.engine.EngineJob.callCallbackOnResourceReady(EngineJob.java:152) at com.bumptech.glide.load.engine.EngineJob$CallResourceReady.run(EngineJob.java:398) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7529) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
版本:implementation 'com.github.penfeizhou.android.animation:glide-plugin:1.3.1
不是特定的APNG图片导致的崩溃,而是使用ViewPager切换Fragment,Fragment是一个APNG图片列表,在切换的过程中偶尔会出现的异常。
Info | Value | |
---|---|---|
Device Info | vivo Y66 | |
System Version | 6.0.1 | |
APNG4Android Library Version | 1.3.3 |
java.lang.IllegalArgumentException: Problem decoding into existing bitmap
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:525)
at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw(APNGFrame.java:133)
at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw(APNGFrame.java:22)
at com.github.penfeizhou.animation.apng.decode.APNGDecoder.renderFrame(APNGDecoder.java:190)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.step(FrameSeqDecoder.java:451)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.access$200(FrameSeqDecoder.java:34)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder$1.run(FrameSeqDecoder.java:58)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.os.HandlerThread.run(HandlerThread.java:61)
I am using this library. And it is very cool compared to others...
However, the ratio seems fixed. is there any way to change it into match_parent/match_parent?
I noticed when cleaning the cache a bunch of warning:
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.io.FileInputStream.open0(Native Method)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.io.FileInputStream.open(FileInputStream.java:231)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.io.FileInputStream.<init>(FileInputStream.java:165)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.io.FileReader.reset(FileReader.java:24)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.io.FilterReader.reset(FilterReader.java:30)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGFrame.encode(APNGFrame.java:89)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw(APNGFrame.java:126)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGFrame.draw(APNGFrame.java:22)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.apng.decode.APNGDecoder.renderFrame(APNGDecoder.java:190)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.decode.FrameSeqDecoder.step(FrameSeqDecoder.java:463)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.decode.FrameSeqDecoder.access$200(FrameSeqDecoder.java:35)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at com.github.penfeizhou.animation.decode.FrameSeqDecoder$1.run(FrameSeqDecoder.java:56)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.util.concurrent.ThreadPoolExecutor.processTask(ThreadPoolExecutor.java:1187)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1152)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2019-08-24 12:18:14.988 17833-18021/app.fedilab.android W/System.err: at java.lang.Thread.run(Thread.java:784)
2019-08-24 12:18:14.995 17833-18040/app.fedilab.android W/System.err: java.io.FileNotFoundException: /data/user/0/app.fedilab.android/cache/image_manager_disk_cache/5b6ee9e893a2dd423458d69fea72ef028141b23897100f97af8dd83ca2b2e2e5.0 (No such file or directory)
The error is handled in APNGFrame.java
Would it be possible to stop the animation especially for the FileNotFoundException
irrelevant
Caused by: java.lang.NullPointerException:
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.getDesiredSample (FrameSeqDecoder.java:407)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.setDesiredSize (FrameSeqDecoder.java:381)
at com.github.penfeizhou.animation.FrameAnimationDrawable.setBounds (FrameAnimationDrawable.java:128)
at app.fedilab.android.client.Entities.Status$8.onResourceReady (Status.java:895)
at app.fedilab.android.client.Entities.Status$8.onResourceReady (Status.java:885)
I can't reproduce that on my end but I got several reports.
Hey,
When I wanted to debug some crashes I noticed this bug. Is it something that I can fix on my end?
StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
Here are the full logs
2019-08-17 09:22:43.099 16542-16551/app.fedilab.android D/StrictMode: StrictMode policy violation: android.os.strictmode.LeakedClosableViolation: A resource was acquired at attached stack trace but never released. See java.io.Closeable for information on avoiding resource leaks.
at android.os.StrictMode$AndroidCloseGuardReporter.report(StrictMode.java:1803)
at dalvik.system.CloseGuard.warnIfOpen(CloseGuard.java:264)
at java.io.FileInputStream.finalize(FileInputStream.java:487)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:250)
at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:237)
at java.lang.Daemons$Daemon.run(Daemons.java:103)
at java.lang.Thread.run(Thread.java:784)
Caused by: java.lang.Throwable: Explicit termination method 'close' not called
at dalvik.system.CloseGuard.open(CloseGuard.java:221)
at java.io.FileInputStream.<init>(FileInputStream.java:168)
at com.github.penfeizhou.animation.io.FileReader.reset(FileReader.java:24)
at com.github.penfeizhou.animation.io.FilterReader.toInputStream(FilterReader.java:55)
at com.github.penfeizhou.animation.io.FilterReader.toInputStream(FilterReader.java:56)
at com.github.penfeizhou.animation.apng.decode.StillFrame.draw(StillFrame.java:35)
at com.github.penfeizhou.animation.apng.decode.StillFrame.draw(StillFrame.java:19)
at com.github.penfeizhou.animation.apng.decode.APNGDecoder.renderFrame(APNGDecoder.java:190)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.step(FrameSeqDecoder.java:463)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder.access$200(FrameSeqDecoder.java:35)
at com.github.penfeizhou.animation.decode.FrameSeqDecoder$1.run(FrameSeqDecoder.java:56)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:458)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
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:784)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Rect.width()' on a null object reference at com.github.penfeizhou.animation.FrameAnimationDrawable.getIntrinsicWidth(FrameAnimationDrawable.java:196) at android.widget.ImageView.invalidateDrawable(ImageView.java:293) at android.graphics.drawable.Drawable.invalidateSelf(Drawable.java:450) at android.graphics.drawable.Drawable.setVisible(Drawable.java:859) at com.github.penfeizhou.animation.FrameAnimationDrawable.setVisible(FrameAnimationDrawable.java:191) at android.widget.ImageView.updateDrawable(ImageView.java:1061) at android.widget.ImageView.setImageDrawable(ImageView.java:609) at com.bumptech.glide.request.target.DrawableImageViewTarget.setResource(DrawableImageViewTarget.java:28) at com.bumptech.glide.request.target.DrawableImageViewTarget.setResource(DrawableImageViewTarget.java:10) at com.bumptech.glide.request.target.ImageViewTarget.setResourceInternal(ImageViewTarget.java:127) at com.bumptech.glide.request.target.ImageViewTarget.onResourceReady(ImageViewTarget.java:104) at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:582) at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:544) at com.bumptech.glide.load.engine.EngineJob.callCallbackOnResourceReady(EngineJob.java:152) at com.bumptech.glide.load.engine.EngineJob$CallResourceReady.run(EngineJob.java:398) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:101) at android.os.Looper.loop(Looper.java:166) at android.app.ActivityThread.main(ActivityThread.java:7529) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
Info | Value | |
---|---|---|
Device Info | e.g. Huawei Mate 20 | |
System Version | e.g. 9.0 | |
APNG4Android Library Version | e.g. 1.3.1 | |
Repro rate | e.g. all the time (100%) / sometimes x% / only once | |
Repro with our demo project | e.g. does it happen with our demo project? | |
Demo project link | e.g. link to a demo project that highlights the issue |
Please fill in the detailed description of the issue (full output of any stack trace, compiler error, ...) and the steps to reproduce the issue.
加载网络apng动画资源只显示静态图不能播放动画,加载本地资源没有问题
EXCEPTION LOG:
java.lang.IllegalArgumentException: Problem decoding into existing bitmap
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:670)
at com.github.penfeizhou.animation.webp.decode.AnimationFrame.draw(AnimationFrame.java:82)
我看了一下最近1.3.3 change log,增加了一条 Avoid buffer size smaller than the target bitmap。
想确认一下这个是在什么情况下出现的,因为修复的代码只是做了一个防止错误的出现而已,是否彻底解决了问题?
Info | Value | |
---|---|---|
Device Info | VIVO V3 | |
System Version | Android 5.1.1,level 22 | |
APNG4Android Library Version | 1.3.2 | |
Repro rate | Per thousand | |
Repro with our demo project | no | |
Demo project link | e.g. link to a demo project that highlights the issue |
public static final Option<Boolean> DISABLE_ANIMATION_GIF_DECODER = Option.memory( "com.github.penfeizhou.animation.glide.AnimationDecoderOption.DISABLE_ANIMATION_GIF_DECODER", false);
注释里面默认值是true,但是代码里面是false
现在使用glide加载图片,得到的GifDrawable是这个库的,不是glide默认的。
I implemented a function that allows to load GIF if requested but when scrolling down, I have a lot of messages : E/FrameSeqDecoder: Processing,wait for finish at FINISHING
and the app freezes.
I simply use that method:
public static void loadGiF(final Context context, String url, final ImageView imageView){
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
boolean disableGif = sharedpreferences.getBoolean(SET_DISABLE_GIF, false);
Glide.with(imageView.getContext())
.asDrawable()
.thumbnail(0.1f)
.load(url)
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
if( !disableGif) {
resource.setVisible(true, true);
imageView.setImageDrawable(resource);
}else{
resource.setVisible(true, true);
Bitmap bitmap = drawableToBitmap(resource.getCurrent());
imageView.setImageBitmap(bitmap);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
imageView.setClipToOutline(true);
}
imageView.setBackgroundResource(R.drawable.rounded_corner_10);
}
});
}
and in my adapter:
loadGiF(context, account.getAvatar(), holder.status_account_profile);
Currently it's possible to use ResourceStreamLoader from a drawable:
// Load form Resource
ResourceStreamLoader resourceLoader = new ResourceStreamLoader(context, R.drawable.sample);
Would it be possible to use it with any drawable?
The idea is to use the lib with Glide without the plugin:
Glide.with(context)
.asDrawable()
.load(emoji.getUrl())
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
ResourceStreamLoader resourceLoader = new ResourceStreamLoader(context, resource);
}
});
Currently I use File
instead of Drawable
to make it work with Glide.
I try to use APNG4Android with Glide and ImageSpan for displaying animated png like this one
As soon as I import the lib 'com.github.pengfeizhou.android.animation:glide-plugin:0.2.16'
, drawable are no longer displayed. I use this code:
Glide.with(context)
.asDrawable()
.load(emoji.getUrl())
.into(new SimpleTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
resource.setBounds(0,0,(int) Helper.convertDpToPixel(20, context),(int) Helper.convertDpToPixel(20, context));
ImageSpan imageSpan = new ImageSpan(resource, ImageSpan.ALIGN_BASELINE);
contentSpan.setSpan(imageSpan, startPosition,endPosition, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
});
I don't get errors so I guess I am not using it correctly.
hi,
I'm using APNG4Android source code with Glide, when testing ,apng and gif get nothing wrong, but webP seems to have some rendering problem.
Hope you can help me! Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.