I want to generate a list of QR codes (10 in this example).
I'm using RecyclerView adapter and ZXing library, where generateQrCode
method I took from here: https://stackoverflow.com/a/25283174/9311961, which returns a bitmap on 256 x 256 (512 would take too much time):
My first approach was to generate the QRs on the background thread, like this:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val context = holder.itemView.context
val qrCode = qrCodeList!![position]
println("TIME AT $position: ${getCurrentDateTime()}")
holder.imageIv.setImageBitmap(generateQrCode(context, qrCode.qr))
// ...
}
I got these times as response:
I/System.out: TIME AT 0: 2019-08-23 11:25:14
I/System.out: TIME AT 1: 2019-08-23 11:25:15
I/System.out: TIME AT 2: 2019-08-23 11:25:16
I/System.out: TIME AT 3: 2019-08-23 11:25:16
I/System.out: TIME AT 4: 2019-08-23 11:25:17
I/System.out: TIME AT 5: 2019-08-23 11:25:17
I/System.out: TIME AT 6: 2019-08-23 11:25:18
I/System.out: TIME AT 7: 2019-08-23 11:25:18
I/System.out: TIME AT 8: 2019-08-23 11:25:19
I/System.out: TIME AT 9: 2019-08-23 11:25:20
=> 6 seconds
But the problem is, that this approach will block my screen until the QRs are generated.
My second approach was to generate the QRs using RxJava, avoiding background thread:
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val context = holder.itemView.context
val qrCode = qrCodeList!![position]
val array = arrayListOf(qrCode.qr, holder.imageIv, position)
println("TIME START: ${getCurrentDateTime()}")
Single.just(array)
.subscribeOn(Schedulers.computation()).map {
val bitmap = generateQrCode(context, it[0] as String)
arrayListOf(bitmap, it[1], it[2])
}
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onGenerateQrCodeSuccess, this::onGenerateQrCodeError)
// ...
}
private fun onGenerateQrCodeSuccess(array: ArrayList<Any>) {
val qrCode = array[0] as Bitmap
val imageView = array[1] as AppCompatImageView
val position = array[2] as Int
println("TIME AT $position: ${getCurrentDateTime()}")
imageView.setImageBitmap(qrCode)
}
private fun onGenerateQrCodeError(throwable: Throwable) {
println("ERROR WHILE GENERATING QR: $throwable")
}
I got these times as response:
I/System.out: TIME START: 2019-08-23 12:15:32
I/System.out: TIME AT 0: 2019-08-23 12:15:43
I/System.out: TIME AT 2: 2019-08-23 12:15:44
I/System.out: TIME AT 3: 2019-08-23 12:15:44
I/System.out: TIME AT 1: 2019-08-23 12:15:45
I/System.out: TIME AT 4: 2019-08-23 12:15:54
I/System.out: TIME AT 6: 2019-08-23 12:15:55
I/System.out: TIME AT 7: 2019-08-23 12:15:55
I/System.out: TIME AT 5: 2019-08-23 12:15:55
I/System.out: TIME AT 8: 2019-08-23 12:15:57
I/System.out: TIME AT 9: 2019-08-23 12:15:57
=> 25 seconds
It's much more time than generating QRs from background thread.
It would be nice to achieve the time I got in first approach without having my screen blocked.
So how could I obtain a fast QRs generating by using RxJava (or in any other way), to not have my screen blocked until these are displayed?