# android-gif-drawable: Rendering Animated GIFs in Android Views

> android-gif-drawable bundles GIFLib through JNI so Android can animate GIFs in ordinary ImageView-style widgets. Here is how the mechanism works, how to install it, and where it stops being the right tool.

**koral--/android-gif-drawable** — Views and Drawable for displaying animated GIFs on Android

- Repository: https://github.com/koral--/android-gif-drawable
- Stars: 9,647 · Forks: 1,789
- Language: Java
- License: NOASSERTION
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/koral-android-gif-drawable

## The gap android-gif-drawable fills on Android

Android's own widget toolkit does not animate GIFs. A plain ImageView draws the first frame and stops. The README frames the project's purpose directly: bundled GIFLib via JNI is used to render frames, and the README states this way should be more efficient than WebView or Movie classes. That is the whole pitch, and it is a narrow one. The library is for Android developers who have a GIF asset (a loading spinner, a sticker, a short loop in a chat or product screen) and want it to play inside a normal view hierarchy rather than inside a WebView or a video surface. The project ships Java sources plus native code, and the repository layout reflects that: a top-level android-gif-drawable module, a sample module, and Gradle wrapper files. The last push to the default branch was on 2026-06-23, and the most recent release listed is v1.2.32 from 2026-06-18. The repository is not archived.

## How GIFLib through JNI actually renders a frame

The mechanism is worth understanding before you adopt it, because it explains both the performance story and the constraints. GIFLib is compiled as native code and reached through JNI. Frames are not all decoded up front. According to the README, subsequent frames are decoded on demand from the source, and this is why every input source must be able to rewind to the beginning: the animation is repeatable, so the decoder returns to the start of the stream as it loops. That design keeps memory use tied to the current frame rather than the whole file, but it means the library holds a live handle on your input. The README is explicit about ownership: when you pass an InputStream, FileDescriptor or AssetFileDescriptor, the library takes ownership and closes it, so you must not close it yourself. InputStreams are closed automatically in the finalizer if the GifDrawable is no longer needed, and calling recycle() also closes the underlying input source. Relying on a finalizer for cleanup is a trade-off, not a feature. If you hand the library a stream and never call recycle(), you are depending on garbage collection timing to release the source. The README does not document a deterministic close path beyond recycle().

## Installing android-gif-drawable from Maven Central

The README gives the Gradle dependency directly. Add it to the module that needs it, and make sure Maven Central is in your repositories block, because the README notes that the Maven Central repository should be defined.

```groovy
dependencies {
    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.32'
}
```

If you prefer Maven coordinates, the README shows the same artifact as a dependency with groupId pl.droidsonroids.gif, artifactId android-gif-drawable and type aar. The README does not pin a version there; it says to insert the latest version. Development builds from the dev branch are published to the OSS snapshot repository, and the README shows how to add https://oss.sonatype.org/content/repositories/snapshots to your repositories block and depend on 1.2.+ if you want them. That is a snapshot, so treat it as such. The README also points to an Eclipse sample project and to the latest release downloads page for people who are not on Gradle. Requirements are stated plainly: Android 4.2+ (API level 17+), hardware-accelerated rendering for GifTextureView, and OpenGL ES 2.0+ for GifTexImage2D. Building from source needs the Android NDK to compile the native sources.

## Your first GifImageView in XML and Java

The simplest path is XML. Drop a GifImageView in place of an ImageView and point android:src at a GIF. The README states that if the drawables declared by android:src or android:background are GIF files, they are automatically recognized as GifDrawables and animated; if the drawable is not a GIF, the view behaves like a plain ImageView.

```xml
<pl.droidsonroids.gif.GifImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:src="@drawable/src_anim"
    android:background="@drawable/bg_anim"
    />
```

For code paths where the source is not a resource, construct a GifDrawable directly. The README lists constructors for assets, resources, Uri, byte array, FileDescriptor, file path, File, AssetFileDescriptor, InputStream and ByteBuffer. Here is the resource case:

```java
GifDrawable gifFromResource = new GifDrawable( getResources(), R.drawable.anim );
```

Once you have the drawable, animation control comes from Animatable and MediaPlayerControl. The README documents stop(), start(), isRunning(), reset(), setSpeed(float factor) (passing 2.0f doubles the speed), and seekTo(int position) in milliseconds within the current loop. stop() and start() can be called from any thread. If you need a Uri source, note the README's caveat that the ContentResolver can be null for file:// Uris.

## Where the library is the wrong choice

The API 17 floor is the first hard boundary. If your minimum SDK is below 17, this library is not an option, and the README states the requirement without offering a fallback. The second boundary is the rewind requirement. The README says all input sources need the ability to rewind to the beginning, and it notes that an InputStream must support marking. A one-shot network stream that cannot seek will not work as a source; you have to buffer it into something seekable first. Third, GifTextureView needs hardware-accelerated rendering, and GifTexImage2D needs OpenGL ES 2.0+, so those two classes are not drop-in replacements in every rendering context. Fourth, the sample project is described in the README as under construction, with not all features covered. That is a documentation gap you will feel if you are trying to learn the API from examples rather than from Javadoc. Finally, this library is about GIF. If your asset pipeline has moved to animated WebP or to short video, the library does not address that, and the README does not claim otherwise.

## android-gif-drawable compared with WebView and Movie

The README itself names the alternatives: WebView and the Movie class, and states that the bundled GIFLib approach should be more efficient than either. The difference in approach matters. WebView brings a full browser engine into your layout to decode and paint a GIF; you get HTML and CSS around the animation, but you also carry the weight of that engine and you lose the ordinary View contract (no simple setImageResource, no Animatable methods on your drawable). Movie is the older Android class for frame-by-frame playback, and it does not integrate with the ImageView drawable pipeline the way GifDrawable does. With android-gif-drawable, the GIF is a Drawable, so it participates in the normal Android rendering path, and the animation controls (start, stop, reset, setSpeed, seekTo) are methods on that drawable. That is the real distinction: not just speed, but whether the animated asset behaves like a first-class view citizen. If you need the GIF inside a WebView-based screen anyway, the comparison flips and the WebView may be simpler.

## Licence, upgrade cost and what the repository tells you

The repository carries a LICENSE file at the top level, and the metadata records the licence as NOASSERTION, which means the licence could not be automatically classified. That is a signal to open the LICENSE file and read it yourself before you ship, particularly because the project bundles GIFLib as native code. The licence of the bundled GIFLib is not described in the README, and the README does not discuss licence implications at all. This is not legal advice; it is a pointer to the two files you should read. On upgrade cost, the release cadence visible in the metadata is modest: v1.2.30 on 2025-12-23, v1.2.31 on 2026-02-12, and v1.2.32 on 2026-06-18, with the last push on 2026-06-23. There is a CHANGELOG.md at the top level, which is where you should look for breaking changes between those versions. The README does not document a rollback procedure or a compatibility policy across minor versions, so pinning an explicit version such as 1.2.32 rather than a range is the safer default.

## Conclusion

Adopt android-gif-drawable when you need animated GIFs inside standard Android views and can meet the API 17+ floor. Do not adopt it if your app must run below API 17, if you need animated WebP or video, or if you cannot accept a bundled native library in your APK. Before committing, verify that your Gradle configuration resolves pl.droidsonroids.gif:android-gif-drawable:1.2.32 from Maven Central, and confirm the View class you intend to use is covered by the README's documented set (GifImageView, GifImageButton, GifTextView).

## FAQ

### How do you do GIFs on Android with android-gif-drawable?

Add the dependency pl.droidsonroids.gif:android-gif-drawable:1.2.32 to your module's build.gradle, make sure Maven Central is declared in your repositories block, and then use GifImageView in XML or construct a GifDrawable from a resource, asset, Uri or file. The README states that GIF drawables set via android:src or android:background are automatically recognized and animated.

### Do GIFs work on Android with android-gif-drawable?

Yes, but not through the platform widgets alone. The README states that android-gif-drawable uses bundled GIFLib via JNI to render frames, and that a plain drawable that is not a GIF makes the library's views behave like ordinary ImageView and ImageButton. Requirements are Android 4.2+ (API level 17+).

### Does android-gif-drawable close the InputStream I pass to it?

Yes. The README states that when you pass an InputStream, FileDescriptor or AssetFileDescriptor, the library takes ownership and closes it, so you must not close it yourself. Calling recycle() also closes the underlying input source, and InputStreams are closed automatically in the finalizer if the GifDrawable is no longer needed.

### Can I control the speed of an animated GIF with android-gif-drawable?

Yes. GifDrawable implements Animatable and MediaPlayerControl, and the README documents setSpeed(float factor), where passing 2.0f doubles the animation speed. It also documents stop(), start(), isRunning(), reset() and seekTo(int position) in milliseconds within the current loop.

### What Android version does android-gif-drawable require?

The README states Android 4.2+ (API level 17+). GifTextureView additionally needs hardware-accelerated rendering, and GifTexImage2D needs OpenGL ES 2.0+.

## Sources

- [Issues](https://github.com/koral--/android-gif-drawable/issues)
- [koral--/android-gif-drawable on GitHub](https://github.com/koral--/android-gif-drawable)
- [README](https://github.com/koral--/android-gif-drawable/blob/dev/README.md)
- [Releases](https://github.com/koral--/android-gif-drawable/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/koral-android-gif-drawable
