android 그림 불 러 오기 OOM (out of memory) 은 캐 시 크기 설정 을 지원 합 니 다. 더 이상 catch OOM 을 강제 하지 않 습 니 다.
package l.test1.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
public class BitmapUtil {
private static final Size ZERO_SIZE = new Size(0,0);
private static final Options OPTIONS_GET_SIZE = new Options();
private static final Options OPTIONS_DECODE = new Options();
static{
OPTIONS_GET_SIZE.inJustDecodeBounds = true;
}
public static Size getBitMapSize(String path){
File file = new File(path);
if(file.exists()){
InputStream in = null;
try{
in = new FileInputStream(file);
BitmapFactory.decodeStream(in, null, OPTIONS_GET_SIZE);
return new Size(OPTIONS_GET_SIZE.outWidth,OPTIONS_GET_SIZE.outHeight);
} catch (FileNotFoundException e) {
return ZERO_SIZE;
}finally{
closeInputStream(in);
}
}
return ZERO_SIZE;
}
public static Bitmap createBitmap(String path,int width,int height){
File file = new File(path);
if(file.exists()){
InputStream in = null;
try {
in = new FileInputStream(file);
Size size = getBitMapSize(path);
if(size.equals(ZERO_SIZE)){
return null;
}
int scale = 1;
int a = size.getWidth() / width;
int b = size.getHeight() / height;
scale = Math.max(a, b);
synchronized (OPTIONS_DECODE) {
OPTIONS_DECODE.inSampleSize = scale;
Bitmap bitMap = BitmapFactory.decodeStream(in,null,OPTIONS_DECODE);
return bitMap;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
finally{
closeInputStream(in);
}
}
return null;
}
public static void destory(Bitmap bitmap){
if(null != bitmap && !bitmap.isRecycled()){
bitmap.recycle();
bitmap = null;
}
}
private static void closeInputStream(InputStream in) {
if(null != in){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class Size{
private int width,height;
Size(int width,int height){
this.width = width;
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
package l.test1.util;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import android.graphics.Bitmap;
/**
* Bitmap , , , Bitmap
* :
* Bitmap , Bitmap
* , ,
* ,
* @author liaoxingliao
*
*/
public final class BitMapLRU {
private static int CACHE_BYTE_SIZE = 10*1024*1024; // 10M
private static int CACHE_SIZE = 2000; //
private static int byteSize = 0;
private static final byte[] LOCKED = new byte[0];
private static final LinkedList<String> CACHE_ENTRIES = // Bitmap ,
new LinkedList<String>(){
private static final long serialVersionUID = 1L;
@Override
public void addFirst(String object) {
while(remove(object));
super.addFirst(object);
}
};
private static final Stack<QueueEntry> TASK_QUEUE = new Stack<QueueEntry>(); //
private static final Set<String> TASK_QUEUE_INDEX = new HashSet<String>(); // key,
private static final Map<String,Bitmap> IMG_CACHE_INDEX = new HashMap<String,Bitmap>(); // Bitmap ,
static{
// ,
new Thread(){
{setDaemon(true);}
public void run() {
while(true) {
synchronized (TASK_QUEUE) {
if(TASK_QUEUE.isEmpty()) {
try {
TASK_QUEUE.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
QueueEntry entry = TASK_QUEUE.pop();
String key = createKey(entry.path,entry.width,entry.height);
TASK_QUEUE_INDEX.remove(key);
createBitmap(entry.path, entry.width, entry.height);
}
}
}.start();
}
/**
* , , ,
* , , , , , ,
* @param path ( , )
* @param width
* @param height
* @return
*/
public static Bitmap createBitmap(String path, int width, int height) {
Bitmap bitMap = null;
try{
while(CACHE_ENTRIES.size() >= CACHE_SIZE || byteSize >= CACHE_BYTE_SIZE) {
destoryLast();
}
bitMap = useBitmap(path, width, height);
if( bitMap != null && !bitMap.isRecycled()){
return bitMap;//4294967296
}
bitMap = BitmapUtil.createBitmap(path, width, height);
if(bitMap == null) { // ..
return null;
}
byteSize += (bitMap.getRowBytes() * bitMap.getHeight());
String key = createKey(path,width,height);
synchronized (LOCKED) {
IMG_CACHE_INDEX.put(key, bitMap);
CACHE_ENTRIES.addFirst(key);
}
}catch(OutOfMemoryError err) {
System.out.println("OOM:" + byteSize);
destoryLast();
return createBitmap(path, width, height);
}
return bitMap;
}
/**
* ,
* @param size
*/
public static void setCacheSize(int size) {
if(size <=0 ){
throw new RuntimeException("size :"+size);
}
while(size < CACHE_ENTRIES.size()){
destoryLast();
}
CACHE_SIZE = size;
}
/**
*
* @param path ( )
* @param width
* @param height
*/
public static void addTask(String path, int width, int height) {
QueueEntry entry = new QueueEntry();
entry.path = path;
entry.width = width;
entry.height = height;
synchronized (TASK_QUEUE) {
while(TASK_QUEUE.size() > 20) {
QueueEntry e = TASK_QUEUE.lastElement();
TASK_QUEUE.remove(e);
TASK_QUEUE_INDEX.remove(createKey(e.path, e.width, e.height));
}
String key = createKey(path,width,height);
if(!TASK_QUEUE_INDEX.contains(key) && !IMG_CACHE_INDEX.containsKey(key)){
TASK_QUEUE.push(entry);
TASK_QUEUE_INDEX.add(key);
TASK_QUEUE.notify();
}
}
}
public static void cleanTask() {
synchronized (TASK_QUEUE) {
TASK_QUEUE_INDEX.clear();
TASK_QUEUE.clear();
}
}
//
private static Bitmap useBitmap(String path,int width,int height) {
Bitmap bitMap = null;
String key = createKey(path,width,height);
synchronized (LOCKED) {
bitMap = IMG_CACHE_INDEX.get(key);
if(null != bitMap){
CACHE_ENTRIES.addFirst(key);
}
}
return bitMap;
}
//
private static void destoryLast() {
synchronized (LOCKED) {
if(!CACHE_ENTRIES.isEmpty()) {
String key = CACHE_ENTRIES.removeLast();
if(key.length() > 0) {
Bitmap bitMap = IMG_CACHE_INDEX.remove(key);
if(bitMap != null) {
bitMap.recycle();
byteSize -= (bitMap.getRowBytes() * bitMap.getHeight());
bitMap = null;
}
}
}
}
}
//
private static String createKey(String path,int width,int height) {
if(null == path || path.length() == 0) {
return "";
}
return path+"_"+width+"_"+height;
}
//
static class QueueEntry{
public String path;
public int width;
public int height;
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.