These are chat archives for ReactiveX/RxJava

15th
Oct 2017
Ethan Le
@quanlt
Oct 15 2017 09:38

Hello guys! i have a problem with rxjava.
I have a list of image url and i need to convert it to jpeg, so i tried

Observable.fromIterable(entries)
       .concatMap(entry->Observable.just(ImageUtils.convertFile(entry.getPath())))
       .subscribeOn(Schedulers.io())

in ImageUtils.convertFile, i decode bitmap then convert it to jpeg.
It worked well on my Galaxy S7 Edge :tada:, but it throw out of memory exception in BitmapFactory.decodeFile (ImageUtils) :( on low-end devices.
At first, i though it's because BitmapFactory.decodeFile use too much memory, but then i realize it can be error of Schedulers.io().
Do you have any advice to solve this problem? Thank you so much:D

Tabiul
@tabiul
Oct 15 2017 10:07
@quanlt why do you think it have to do with Schedulers.io ?
I am new to Rx and RxJava, I am trying a very simple example Observable<String> ob = Observable.<String>create(t -> t.onNext("1")). concatWith(Observable.create(t -> t.onNext("2"))); ob.subscribe(System.out::println);. For some reason it only prints 1. Any idea why ?
Ethan Le
@quanlt
Oct 15 2017 10:47
@tabiul i think it's because Schedulers.io have a limited memory, and decode bitmap consumes many memory
i'm quite new with rxjava too :(
ViTORossonero
@ViTORossonero
Oct 15 2017 11:18

@quanlt Taking into account that you are working with bitmaps, I'd say that Schedulers#io has nothing to do with OOM in this case

code that you provided shouldn't process few bitmaps in parallel so you'd rather check your ImageUtils#convertFile

@tabiul
Observable#concatWith will subscribe to Observable that passed as its param only after parent Observable:

Observable.<String>create(t -> t.onNext("1"))

completes, but in our case it won't complete ever

Ethan Le
@quanlt
Oct 15 2017 11:42
@ViTORossonero , i didn't process it in parallel,
public static File copyFile(PhotoEntry entry, final Context context) throws IOException {
        File file = new File(entry.getPath());
        InputStream in = new FileInputStream(file);
        File outputDir = new File(context.getFilesDir() + IMAGE_TMP_FOLDER);
        if (!outputDir.exists()) {
            outputDir.mkdir();
        }
        File outputFile = new File(context.getFilesDir() + IMAGE_TMP_FOLDER + "/" + entry.getName() + JPEG_EXTENSION);
        try {
            Bitmap bitmap = BitmapFactory.decodeFile(entry.getPath());
            OutputStream out = new FileOutputStream(outputFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
            ImageUtils.copyExif(entry.getPath(), outputFile.getPath());
            bitmap.recycle();
        } finally {
            in.close();
        }
        return outputFile;
    }
i've just tried with asynctask, and it didn't help, that mean you were right about Schedulers.io
Tabiul
@tabiul
Oct 15 2017 22:09
@ViTORossonero , looks like you are right, so it works once I complete the first observable. Thanks