Android|giflib加载GIF

?giflib是一款用C语言写的加载GIF库,在性能方面比Glide要好很多,首先来看一下性能对比。
Android|giflib加载GIF
文章图片

glide加载gif Android|giflib加载GIF
文章图片

giflib加载gif ?从上图中我们可以看出在CPU使用率上,giflib比glide好很多了,内存占用上giflib比glide也要好一些。那么如何使用giflib尼?
?首先需要下载framesequence及giflib(以上网站需要,请自备梯子)
?giflib文件目录如下:
Android|giflib加载GIF
文章图片

?framesequence文件目录如下:
Android|giflib加载GIF
文章图片

?下载完毕后,我们就将framesequence下的jni目录复制到as的main下,giflib复制到jni/giflib目录下。目录结构如下(删除了与webp相关的文件):
【Android|giflib加载GIF】Android|giflib加载GIF
文章图片

?这样就可以开始编译so文件了,但是由于giflib使用的是Android.bp进行编译的(不会呀o(╥﹏╥)o)。所有我就根据Android.bp来重新写了份Android.mk文件,然后ndk-build该文件即可。

# # Copyright (C) 2014 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := gif LOCAL_SRC_FILES := \ giflib/dgif_lib.c \ giflib/egif_lib.c \ giflib/gifalloc.c \ giflib/gif_err.c \ giflib/gif_hash.c \ giflib/openbsd-reallocarray.c \ giflib/quantize.cLOCAL_CFLAGS += \ -Werror \ -Wno-format \ -Wno-sign-compare \ -Wno-unused-parameter \ -DHAVE_CONFIG_H \LOCAL_SDK_VERSION := 8include $(BUILD_STATIC_LIBRARY)include $(CLEAR_VARS) ## Main libraryLOCAL_STATIC_LIBRARIES := gifLOCAL_LDFLAGS := -llog -ljnigraphicsLOCAL_C_INCLUDES := \ giflibLOCAL_MODULE := framesequence LOCAL_SRC_FILES := \ BitmapDecoderJNI.cpp \ FrameSequence.cpp \ FrameSequenceJNI.cpp \ FrameSequence_gif.cpp \ JNIHelpers.cpp \ Registry.cpp \ Stream.cppifeq ($(FRAMESEQUENCE_INCLUDE_WEBP),true) LOCAL_C_INCLUDES += external/webp/include LOCAL_SRC_FILES += FrameSequence_webp.cpp LOCAL_STATIC_LIBRARIES += libwebp-decode endifLOCAL_CFLAGS += \ -Wall \ -Werror \ -Wno-unused-parameter \ -Wno-unused-variable \ -Wno-overloaded-virtual \ -fvisibility=hidden \LOCAL_SDK_VERSION := 8include $(BUILD_SHARED_LIBRARY)

?由于没有使用CMake,所以应该在build.gradle下进行如下配置
externalNativeBuild{
ndkBuild{
path “src/main/jni/Android.mk”
}
}
?最后我们点击rebuild即可生成so文件。那么如何使用尼?
?在使用之前需要将framesequence目录下的src里面的所有文件拷贝到as的Java目录下。然后就可以使用了。使用代码如下(也可以去阅读framesequence下的示例代码):
FrameSequenceDrawable mDrawable; int mResourceId; // This provider is entirely unnecessary, just here to validate the acquire/release process private class CheckingProvider implements FrameSequenceDrawable.BitmapProvider { HashSet mBitmaps = new HashSet(); @Override public Bitmap acquireBitmap(int minWidth, int minHeight) { Bitmap bitmap = Bitmap.createBitmap(minWidth + 1, minHeight + 4, Bitmap.Config.ARGB_8888); mBitmaps.add(bitmap); return bitmap; }@Override public void releaseBitmap(Bitmap bitmap) { if (!mBitmaps.contains(bitmap)) throw new IllegalStateException(); mBitmaps.remove(bitmap); bitmap.recycle(); }public boolean isEmpty() { return mBitmaps.isEmpty(); } }final CheckingProvider mProvider = new CheckingProvider(); //传入资源,设置相关参数 InputStream is = getResources().openRawResource(mResourceId); FrameSequence fs = FrameSequence.decodeStream(is); //传入的是InputStream mDrawable = new FrameSequenceDrawable(fs, mProvider); //mDrawable.setLoopBehavior(LOOP_FINITE); //只播放一次 mDrawable.setOnFinishedListener(new FrameSequenceDrawable.OnFinishedListener() { @Override public void onFinished(FrameSequenceDrawable drawable) { Toast.makeText(getApplicationContext(), "The animation has finished", Toast.LENGTH_SHORT).show(); } }); drawableView.setBackgroundDrawable(mDrawable); //开始播放 mDrawable.start(); //暂停播放 mDrawable.stop(); //裁剪成圆形 mDrawable.setCircleMaskEnabled(!mDrawable.getCircleMaskEnabled());

?目前giflib加载的都是本地的,那么如何加载线上GIF尼?其实可以把giflib与glide结合起来,由glide负责下载、缓存等的实现,giflib来负责GIF的加载。具体实现可以参考我写的一个demo

    推荐阅读