关于android创建bitmap内存爆掉问题

Jachon 2013-09-05 01:32:25
自己做了个测试,同样加载代码解析图片文件流,一种是在assets下面一种是在sd下面,代码下放上来。
for(int i=0; i<40; i++){
BitmapFactory.Options op = new BitmapFactory.Options();
op.inPurgeable = true;
op.inInputShareable = true;
op.inPreferredConfig = Bitmap.Config.RGB_565;
// InputStream in = getAssets().open(""+Res.ui_mainmenu_icon_00_92_png);//SD卡
InputStream in = ResourceManager.getInstance().getResource(Res.ui_mainmenu_icon_00_92_png);//assets下
Log.i("ddd", "EEE" + in.available());
buff[i] = BitmapFactory.decodeStream(in, null, op);
}

图片是相同的图片,只有加载流的方式不同,加载assets下的图片资源时占内存为78%左右,加载sd卡的占内存97%左右。
下面是加载sd卡的代码
public InputStream getResource(int resId){
InputStream in = null;
try {
File file = new File(sdcardPath + resId);
if (file.exists()) {
return new FileInputStream(file);
} else {
in = activity.getAssets().open("" + resId);
}
} catch (IOException e) {
e.printStackTrace();
}
return in;
}


我抓取了内存快照分析,图片奉上
下图是加载assets下资源的内存快照

下图是加载sd卡的内存快照


请问下各位,为什么assets下加载的资源在快照图中没有看到byte数组?
估计是数组导致内存爆掉,请问有经验的朋友解答!
...全文
436 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
ylplonely 2014-08-24
  • 打赏
  • 举报
回复
我还是没有理解该怎么做
Jachon 2013-09-05
  • 打赏
  • 举报
回复
引用 5 楼 guoyoulei520 的回复:
[quote=引用 4 楼 codeshine 的回复:] [quote=引用 3 楼 tanwei4199 的回复:] 额 破解了什么
破了...这个是我跟到源码去看到..虽然不懂...但是觉得科技含量很高的样子..采取替代方案..用字节数组加载..直接破掉..[/quote] 这都被你看到了,不错,学习精神可嘉[/quote] 请问知道是什么原因么..
凉凉二点凉 2013-09-05
  • 打赏
  • 举报
回复
引用 4 楼 codeshine 的回复:
[quote=引用 3 楼 tanwei4199 的回复:] 额 破解了什么
破了...这个是我跟到源码去看到..虽然不懂...但是觉得科技含量很高的样子..采取替代方案..用字节数组加载..直接破掉..[/quote] 这都被你看到了,不错,学习精神可嘉
Jachon 2013-09-05
  • 打赏
  • 举报
回复
引用 3 楼 tanwei4199 的回复:
额 破解了什么
破了...这个是我跟到源码去看到..虽然不懂...但是觉得科技含量很高的样子..采取替代方案..用字节数组加载..直接破掉..
荒颜 2013-09-05
  • 打赏
  • 举报
回复
额 破解了什么
Jachon 2013-09-05
  • 打赏
  • 举报
回复
已经破解了问题了...源码奉上...本事SDK加载就做了特殊处理了..这不是坑人么..歧视普通加载么.. 谁能破?
 public static Bitmap decodeStream(InputStream is, Rect outPadding, Options opts) {
        // we don't throw in this case, thus allowing the caller to only check
        // the cache, and not force the image to be decoded.
        if (is == null) {
            return null;
        }

        // we need mark/reset to work properly

        if (!is.markSupported()) {
            is = new BufferedInputStream(is, DECODE_BUFFER_SIZE);
        }

        // so we can call reset() if a given codec gives up after reading up to
        // this many bytes. FIXME: need to find out from the codecs what this
        // value should be.
        is.mark(1024);

        Bitmap bm;
        boolean finish = true;

        if (is instanceof AssetManager.AssetInputStream) {
            final int asset = ((AssetManager.AssetInputStream) is).getAssetInt();

            if (opts == null || (opts.inScaled && opts.inBitmap == null)) {
                float scale = 1.0f;
                int targetDensity = 0;
                if (opts != null) {
                    final int density = opts.inDensity;
                    targetDensity = opts.inTargetDensity;
                    if (density != 0 && targetDensity != 0) {
                        scale = targetDensity / (float) density;
                    }
                }

                bm = nativeDecodeAsset(asset, outPadding, opts, true, scale);
                if (bm != null && targetDensity != 0) bm.setDensity(targetDensity);

                finish = false;
            } else {
                bm = nativeDecodeAsset(asset, outPadding, opts);
            }
        } else {
            // pass some temp storage down to the native code. 1024 is made up,
            // but should be large enough to avoid too many small calls back
            // into is.read(...) This number is not related to the value passed
            // to mark(...) above.
            byte [] tempStorage = null;
            if (opts != null) tempStorage = opts.inTempStorage;
            if (tempStorage == null) tempStorage = new byte[16 * 1024];

            if (opts == null || (opts.inScaled && opts.inBitmap == null)) {
                float scale = 1.0f;
                int targetDensity = 0;
                if (opts != null) {
                    final int density = opts.inDensity;
                    targetDensity = opts.inTargetDensity;
                    if (density != 0 && targetDensity != 0) {
                        scale = targetDensity / (float) density;
                    }
                }

                bm = nativeDecodeStream(is, tempStorage, outPadding, opts, true, scale);
                if (bm != null && targetDensity != 0) bm.setDensity(targetDensity);

                finish = false;
            } else {
                bm = nativeDecodeStream(is, tempStorage, outPadding, opts);
            }
        }

        if (bm == null && opts != null && opts.inBitmap != null) {
            throw new IllegalArgumentException("Problem decoding into existing bitmap");
        }

        return finish ? finishDecode(bm, outPadding, opts) : bm;
    }

80,471

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧