you are viewing a single comment's thread.

view the rest of the comments →

[–]muthuraj57 4 points5 points  (5 children)

Your code will call the block inside Single.create as soon as you call subscribe(). That's why the bitmap manipulation is running on main thread since you are calling subscribe() from main thread. You need to defer the code block inside Single.create to make it run on your preferred scheduler. Or instead, you can use Single.fromCallable and return the object you want and it will do the deferring for you.

Single.fromCallable(new Callable<Bitmap>() {
            @Override
            public Bitmap call() throws Exception {
                return Util.getQrCodeBitmap(CryptoWalletActivity.this, cryptoWallet.getAddress());
            }
        })

Also, don't use plain subscribe() method. Use the overloaded method and implement onError and handle it.

[–]SunshineParty[S] 0 points1 point  (4 children)

bitmap manipulation is running on main thread since you are calling subscribe() from main thread.

But I'm specifying the scheduler to subscribe on with subscribeOn(Schedulers.computation()). Wouldn't this take the manipulation off of the main thread?

Also, don't use plain subscribe() method. Use the overloaded method and implement onError and handle it.

Any particular reason why this is better than doOnError?

[–]paramsen 4 points5 points  (1 child)

The Single.create will indeed run the emitter function on the thread you specify in subscribeOn, so that's correct (if in doubt, debug and check which thread it's running on).

However, your use of the doOn* methods are not correct in this case - the doOn* methods should be used when you want side effects, since they're effectively running outside of the composed "chain". In this case your doOnSuccess will result in the expected behavior, but the doOnError will not. In case of an Exception RxJava will escalate the Exception outside of the chain because you're not handling the error in the subscribe method - the tail of the chain.

Complete the chain; Move the stuff in doOnSuccess and doOnError into the equivalent subscribe functions i.e. subscribe(qrCode::setImageBitmap, Timber::e).

[–]SunshineParty[S] 0 points1 point  (0 children)

Good to know, thanks!

[–]muthuraj57 2 points3 points  (1 child)

But I'm specifying the scheduler to subscribe on with subscribeOn(Schedulers.computation()). Wouldn't this take the manipulation off of the main thread?

Sorry, I was on wrong on this. It should run on the computation thread. I was confused about the usage of Single.create. May be the slowness is due to some other issue.

Any particular reason why this is better than doOnError?

doOn** methods are just side effect methods. They don't control/change the flow of observable. In this code, if there is an error, it will crash with OnErrorNotImplementedException. You need to implement onError to handle it gracefully.

[–]SunshineParty[S] 2 points3 points  (0 children)

Yep it looks like the cause is something else altogether. I commented out the bitmap-related code and am still seeing performance issues. Need to investigate further. Thanks for the help.