You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxJava处理Bitmap列表:后台缩放、结果获取及错误处理的Subscriber选择

处理Bitmap后台缩放的Observer/Subscriber选择建议

嘿,针对你在后台线程批量缩放Bitmap并收集结果、处理错误的需求,我来给你梳理下合适的方案——分RxJava版本给你具体建议:

先明确核心需求匹配点

你需要:

  • 在后台线程执行耗时的Bitmap缩放,不阻塞主线程
  • 把所有缩放后的Bitmap收集成一个完整列表
  • 能捕获并处理缩放过程中可能出现的异常(比如OOM、Bitmap格式错误等)
  • 最终将结果列表传入目标方法

RxJava 2+版本:优先用DefaultObserver

RxJava 2及以后,Subscriber被拆分为更灵活的Observer接口,而DefaultObserver是官方提供的默认实现,帮你省去了空方法的冗余代码,非常适合你的场景。

基础实现(出错即终止流程)

如果只要有一个Bitmap缩放失败就终止整个任务,用toList()直接收集所有结果:

// 假设你已经有了原始Bitmap列表bitmapList,以及目标宽高targetWidth、targetHeight
Observable.fromIterable(bitmapList)
    .subscribeOn(Schedulers.io()) // 指定后台IO线程执行缩放
    .map(bitmap -> {
        try {
            // 执行缩放逻辑
            return Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, true);
        } catch (Exception e) {
            // 把异常抛出,交给Observer的onError处理
            throw new RuntimeException("Bitmap缩放失败", e);
        }
    })
    .toList() // 自动收集所有处理后的Bitmap为List
    .observeOn(AndroidSchedulers.mainThread()) // 如果目标方法需要在主线程执行(比如更新UI),切换线程
    .subscribe(new DefaultObserver<List<Bitmap>>() {
        @Override
        public void onNext(List<Bitmap> scaledBitmaps) {
            // 成功拿到所有缩放后的Bitmap,传入你的目标方法
            yourTargetProcessingMethod(scaledBitmaps);
        }

        @Override
        public void onError(Throwable e) {
            // 处理错误:打印日志、提示用户、清理临时资源等
            Log.e("BitmapScale", "缩放过程出现异常", e);
            // 这里可以根据异常类型做针对性处理,比如OOM时释放部分Bitmap
        }

        @Override
        public void onComplete() {
            // 收尾工作:回收原始Bitmap(如果不再需要),避免内存泄漏
            for (Bitmap bmp : bitmapList) {
                if (!bmp.isRecycled()) {
                    bmp.recycle();
                }
            }
        }
    });

进阶实现(容忍部分错误)

如果希望某个Bitmap缩放失败时,跳过它继续处理其他图片,改用flatMap结合collect来收集成功的结果:

Observable.fromIterable(bitmapList)
    .subscribeOn(Schedulers.io())
    .flatMap(bitmap -> {
        try {
            Bitmap scaledBmp = Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, true);
            return Observable.just(scaledBmp);
        } catch (Exception e) {
            Log.e("BitmapScale", "单个Bitmap缩放失败,跳过该图片", e);
            // 返回空Observable,不中断整个流
            return Observable.empty();
        }
    })
    .collect(ArrayList::new, List::add) // 收集所有成功缩放的Bitmap
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new DefaultObserver<List<Bitmap>>() {
        @Override
        public void onNext(List<Bitmap> successfulScaledBitmaps) {
            // 拿到所有缩放成功的Bitmap列表,传入目标方法
            yourTargetProcessingMethod(successfulScaledBitmaps);
        }

        @Override
        public void onError(Throwable e) {
            // 只有当流本身出现严重错误(比如线程调度失败)时才会触发
            Log.e("BitmapScale", "缩放流程发生严重异常", e);
        }

        @Override
        public void onComplete() {
            // 回收原始Bitmap资源
            for (Bitmap bmp : bitmapList) {
                if (!bmp.isRecycled()) {
                    bmp.recycle();
                }
            }
        }
    });

RxJava 1版本:用Subscriber即可

如果你还在维护RxJava 1的项目,直接用Subscriber就可以,逻辑和上面一致:

Observable.from(bitmapList)
    .subscribeOn(Schedulers.io())
    .map(bitmap -> {
        try {
            return Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, true);
        } catch (Exception e) {
            throw new RuntimeException("Bitmap缩放失败", e);
        }
    })
    .toList()
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<List<Bitmap>>() {
        @Override
        public void onCompleted() {
            // 回收原始Bitmap
            for (Bitmap bmp : bitmapList) {
                if (!bmp.isRecycled()) {
                    bmp.recycle();
                }
            }
        }

        @Override
        public void onError(Throwable e) {
            Log.e("BitmapScale", "缩放异常", e);
        }

        @Override
        public void onNext(List<Bitmap> scaledBitmaps) {
            yourTargetProcessingMethod(scaledBitmaps);
        }
    });

关键注意事项

  • 线程调度:一定要用subscribeOn(Schedulers.io())把缩放逻辑放在后台,避免卡死UI;如果目标方法涉及UI操作,用observeOn(AndroidSchedulers.mainThread())切换回主线程。
  • 资源回收:Bitmap是重量级对象,处理完成后务必回收原始Bitmap,避免内存溢出。
  • 错误粒度:根据业务需求选择是“出错即终止”还是“跳过错误项”,两种方案都给你列出来了,按需选用。

内容的提问来源于stack exchange,提问作者vihkat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:23:29