致命信号11(SIGSEGV),BitmapFactory.decodeByteArray()中的代码1

时间:2017-06-28 05:33:25

标签: android bitmap android-bitmap

我创建了一个BitmapPool,如下所示。

public class BitmapPool {

private HashMap<Integer, Progress> progMap = new HashMap<Integer, Progress>();
private HashMap<Integer, Bitmap> bitmaps = new HashMap<Integer, Bitmap>();

private BitmapPool() {

}

private static BitmapPool sInstance;

public static synchronized BitmapPool getInstance() {
    if (sInstance == null) {
        synchronized (BitmapPool.class) {
            sInstance = new BitmapPool();
        }
    }
    return sInstance;
}

public synchronized Bitmap getBitmap(byte[] data, int frameNo) {
    ArrayList<Integer> reUseableKeyList = getReuseableBitmapKeyList();
    if (reUseableKeyList.size() == 0) {
        return getNewBitmap(data, frameNo);
    } else {
        return getAndReuseOldBitmap(data, frameNo, reUseableKeyList);
    }
}

private synchronized Bitmap getNewBitmap(byte[] data, int frameNo) {
    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.RGB_565;
    options.inMutable = true;
    options.inSampleSize = 1;
    Bitmap newBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
    progMap.put(frameNo, Progress.INIT_FRAME);
    bitmaps.put(frameNo, newBitmap);
    return newBitmap;
}

private synchronized Bitmap getAndReuseOldBitmap(byte[] data, int frameNo, ArrayList<Integer> reUseableKeyList) {
    // iterate over keyList to check if old bitmap can be used
    for (Integer key : reUseableKeyList) {
        Bitmap b = bitmaps.get(key);
        // get target bitmap bounds for comparing
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = 1;
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(data, 0, data.length, options);

        if (canUseForInBitmap(b, options)) {
            options.inPreferredConfig = Bitmap.Config.RGB_565;
            options.inMutable = true;
            options.inBitmap = b;
            options.inJustDecodeBounds = false;
            Bitmap newBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
            progMap.remove(key);
            progMap.put(frameNo, Progress.INIT_FRAME);
            bitmaps.remove(key);
            bitmaps.put(frameNo, newBitmap);
            b = null;
            return newBitmap;
        }
    }
    // no old bitmap could be used >  return new bitmap
    return getNewBitmap(data, frameNo);
}

@TargetApi(Build.VERSION_CODES.KITKAT)
public synchronized boolean canUseForInBitmap(
        Bitmap candidate, BitmapFactory.Options targetOptions) {
    // From Android 4.4 (KitKat) onward we can re-use if the byte size of
    // the new bitmap is smaller than the reusable bitmap candidate
    // allocation byte count.
    int width = targetOptions.outWidth / targetOptions.inSampleSize;
    int height = targetOptions.outHeight / targetOptions.inSampleSize;
    int byteCount = width * height * getBytesPerPixel(candidate.getConfig());

    try {
        return byteCount <= candidate.getAllocationByteCount();
    } catch (NullPointerException e) {
        return byteCount <= candidate.getHeight() * candidate.getRowBytes();
    }
}

private synchronized ArrayList<Integer> getReuseableBitmapKeyList() {
    ArrayList<Integer> list = new ArrayList<>();
    for (Map.Entry entry : progMap.entrySet()) {
        if (entry.getValue() == Progress.FAILED || entry.getValue() == Progress.USED)
            list.add((int) entry.getKey());
    }
    return list;
}

private int getBytesPerPixel(Bitmap.Config config) {
    if (config == null) {
        config = Bitmap.Config.ARGB_8888;
    }

    int bytesPerPixel;
    switch (config) {
        case ALPHA_8:
            bytesPerPixel = 1;
            break;
        case RGB_565:
        case ARGB_4444:
            bytesPerPixel = 2;
            break;
        case ARGB_8888:
        default:
            bytesPerPixel = 4;
            break;
    }
    return bytesPerPixel;
}

public void terminate() {
    for (Bitmap b : bitmaps.values()) {
        b.recycle();
        b = null;
    }
}
}

我正在检查使用标准代码,如果位图已准备好重复使用,然后将其与inBitmap选项一起使用。这是在多线程环境中完成的。

奇怪的是我得到:  致命信号11(SIGSEGV),BitmapFactory.decodeByteArray()中的代码1 在getAndReuseOldBitmap()。

我无法找出原因。

有人请帮忙。

0 个答案:

没有答案