giflib載入GIF
阿新 • • 發佈:2018-12-18
giflib是一款用C語言寫的載入GIF庫,在效能方面比Glide要好很多,首先來看一下效能對比。
從上圖中我們可以看出在CPU使用率上,giflib比glide好很多了,記憶體佔用上giflib比glide也要好一些。那麼如何使用giflib尼?
首先需要下載framesequence及giflib(以上網站需要翻牆,請自備梯子)
giflib檔案目錄如下:
framesequence檔案目錄如下:
下載完畢後,我們就將framesequence
下的jni目錄複製到as的main下,giflib
jni/giflib
目錄下。目錄結構如下(刪除了與webp相關的檔案):
這樣就可以開始編譯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.c LOCAL_CFLAGS += \ -Werror \ -Wno-format \ -Wno-sign-compare \ -Wno-unused-parameter \ -DHAVE_CONFIG_H \ LOCAL_SDK_VERSION := 8 include $(BUILD_STATIC_LIBRARY) include $(CLEAR_VARS) ## Main library LOCAL_STATIC_LIBRARIES := gif LOCAL_LDFLAGS := -llog -ljnigraphics LOCAL_C_INCLUDES := \ giflib LOCAL_MODULE := framesequence LOCAL_SRC_FILES := \ BitmapDecoderJNI.cpp \ FrameSequence.cpp \ FrameSequenceJNI.cpp \ FrameSequence_gif.cpp \ JNIHelpers.cpp \ Registry.cpp \ Stream.cpp ifeq ($(FRAMESEQUENCE_INCLUDE_WEBP),true) LOCAL_C_INCLUDES += external/webp/include LOCAL_SRC_FILES += FrameSequence_webp.cpp LOCAL_STATIC_LIBRARIES += libwebp-decode endif LOCAL_CFLAGS += \ -Wall \ -Werror \ -Wno-unused-parameter \ -Wno-unused-variable \ -Wno-overloaded-virtual \ -fvisibility=hidden \ LOCAL_SDK_VERSION := 8 include $(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<Bitmap> mBitmaps = new HashSet<Bitmap>();
@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