高效省内存播放序列帧动画控件
Efficient memory province to play the serial frame control, support from the file, resource read sequence frames, memory reuse, read multiple, just a picture of memory, streaming API, a line of code can achieve serial frame animation
Since the Tencent article has always been described only without specific code, this project is the specific implementation of this article,
The basic principle is still a two thread collaboration, the child thread is responsible for decoding pictures, the main thread is responsible for receiving pictures after setting to the View, because of internal memory reuse, and only occupy a picture of memory
2.Performance tests, memory usage, CPU occupancy
(1)Read directly from the 200 diagram, direct OOM
(2)Read while write, memory on OPPO x9007 is as follows:
(3)After the adoption of this project, the memory footprint on x9007 is as follows:
Memory occupies only one image memory, and CPU occupies about 14%, which has met most of the project scenarios, and has no compatibility and decoding efficiency;
project build.gradle add jitpackWarehouse
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
add the plugin to your buildscript:
dependencies {
compile 'com.github.Mr-wangyong:ImageFrame:v1.3.0'
}
The project is refactoring, and part of the API is marked as obsolete. @Deprecated
is not recommended, and the structure instead of ImageFrameHandler
is responsible for handling sequence frame loading through callback OnImageLoadListener
Return the BitmapDrawable
to the external View settings picture, focus on sequence frame processing, easy for external free custom operation; at the same time, API reference AlertDialog
flow type API, more concise and easy to use;
Increased API:
play
build.start();//开始播放序列帧
pause
build.pause();//暂停播放
Specifies starting from a frame:
build.setStartIndex(10)
Specifies to end from a frame:
build.setEndIndex(10)
Support read from the file /Resource directory. Streaming API, concise and easy to use
Read from file:
startImageFrame
method on frame animation sequenceimageFrame.startImageFrame(new ImageFrameHandler.FileHandlerBuilder(file.listFiles())
.setFps(40)// Set FPS (how many frames per second to play, suggest no more than 30, default 30 is too large, device performance is not enough, disk may not read, lost frames)
.setWidth(100)// Set the width of the picture. You must set it internally, otherwise it will not
.setHeight(300)// Set image height must not be ibid
.setStartIndex(10)// Sets the beginning of the sequence frame picture index, which can be specified starting from that picture
.setEndIndex(30)// Set the end of the sequence frame picture index, which can be specified from the end of that picture
.setLoop(true)// Set whether to loop playback
.openLruCache(true)// Sets whether or not to open the LRU cache. If not, it is not recommended to open the loop. If the loop is recommended, it is open, but the performance of several tests is not very differen
.build());// build
File file = new File(testDir);
//Create a FileHandlerBuilder that is similar to API and Android system AlertDialog
ImageFrameHandler build = new ImageFrameHandler.FileHandlerBuilder(file.listFiles())
//File[] must be passed in as a processing source
.setFps(40)
// // Set FPS (how many frames per second to play, suggest no more than 30, default 30 is too large, device performance is not enough, disk may not read, lost frames)
.setWidth(100)
// Set the width of the picture. You must set it internally, otherwise it will not
.setHeight(300)// Set image height must not be ibid
.setStartIndex(10)
// Sets the beginning of the sequence frame picture index, which can be specified starting from that picture
.setEndIndex(30)
// Set the end of the sequence frame picture index, which can be specified from the end of that picture
.setLoop(true)// Set whether to loop playback
.openLruCache(true)// Sets whether or not to open the LRU cache. If not, it is not recommended to open the loop. If the loop is recommended, it is open, but the performance of several tests is not very differen
.setOnImageLoaderListener(new ImageFrameHandler.OnImageLoadListener() {
//Create a listener, listen, parse successfully, and complete parsing
@Override
public void onImageLoad(BitmapDrawable drawable) {
//Set the picture for your View
ViewCompat.setBackground(view,drawable);
}
@Override
public void onPlayFinish() {
}
})
.build();// Build a Handler to handle
build.start();//Begin to play sequence frames
Of course, you can also have stop
, pause
, and more freely control the loading process;
build.start();//Begin to play sequence frames
build.pause();//Pause play
build.stop();//stop play
Read from the Resource directory
The principle is the same, but the build isResourceHandlerBuilder
final int[] resIds = new int[210];
ImageFrameHandler build = new ImageFrameHandler.ResourceHandlerBuilder(getResources(),resIds)//You must pass in the Resource and resIds resources, the ID collection as the processing source
.setFps(40)
// // Set FPS (how many frames per second to play, suggest no more than 30, default 30 is too large, device performance is not enough, disk may not read, lost frames)
.setWidth(100)
// Set the width of the picture. You must set it internally, otherwise it will not
.setHeight(300)// Set image height must not be ibid
.setStartIndex(10)
// Sets the beginning of the sequence frame picture index, which can be specified starting from that picture
.setEndIndex(30)
// Set the end of the sequence frame picture index, which can be specified from the end of that picture
.setLoop(true)// Set whether to loop playback
.openLruCache(true)// Sets whether or not to open the LRU cache. If not, it is not recommended to open the loop. If the loop is recommended, it is open, but the performance of several tests is not very differen
.setOnImageLoaderListener(new ImageFrameHandler.OnImageLoadListener() {
//Create a listener, listen, parse successfully, and complete parsing
@Override
public void onImageLoad(BitmapDrawable drawable) {
//Set the picture for your View
ViewCompat.setBackground(view,drawable);
}
@Override
public void onPlayFinish() {
}
})
.build();// Build a Handler to handle
build.start();//Begin to play sequence frames
Take the picture loading section as a module ImageFrameProxy; API, like ImageFrameView, turns ImageFrameView into an example; you can add more processing after you get the bitmap;
imageFrame.setLoop(true);
imageFrame.stop();
Android About Bitmap reuse:
https://developer.android.com/training/displaying-bitmaps/manage-memory.html#recycle