yujune

fix: fix android ui jank when returnImage set to true.

@@ -79,7 +79,8 @@ dependencies { @@ -79,7 +79,8 @@ dependencies {
79 79
80 implementation 'androidx.camera:camera-lifecycle:1.3.4' 80 implementation 'androidx.camera:camera-lifecycle:1.3.4'
81 implementation 'androidx.camera:camera-camera2:1.3.4' 81 implementation 'androidx.camera:camera-camera2:1.3.4'
  82 + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
82 83
83 testImplementation 'org.jetbrains.kotlin:kotlin-test' 84 testImplementation 'org.jetbrains.kotlin:kotlin-test'
84 - testImplementation 'org.mockito:mockito-core:5.12.0' 85 + testImplementation 'org.mockito:mockito-core:5.12.0'
85 } 86 }
@@ -35,9 +35,12 @@ import dev.steenbakker.mobile_scanner.objects.DetectionSpeed @@ -35,9 +35,12 @@ import dev.steenbakker.mobile_scanner.objects.DetectionSpeed
35 import dev.steenbakker.mobile_scanner.objects.MobileScannerStartParameters 35 import dev.steenbakker.mobile_scanner.objects.MobileScannerStartParameters
36 import dev.steenbakker.mobile_scanner.utils.YuvToRgbConverter 36 import dev.steenbakker.mobile_scanner.utils.YuvToRgbConverter
37 import io.flutter.view.TextureRegistry 37 import io.flutter.view.TextureRegistry
  38 +import kotlinx.coroutines.CoroutineScope
  39 +import kotlinx.coroutines.Dispatchers
  40 +import kotlinx.coroutines.coroutineScope
  41 +import kotlinx.coroutines.launch
38 import java.io.ByteArrayOutputStream 42 import java.io.ByteArrayOutputStream
39 import kotlin.math.roundToInt 43 import kotlin.math.roundToInt
40 -  
41 class MobileScanner( 44 class MobileScanner(
42 private val activity: Activity, 45 private val activity: Activity,
43 private val textureRegistry: TextureRegistry, 46 private val textureRegistry: TextureRegistry,
@@ -97,6 +100,7 @@ class MobileScanner( @@ -97,6 +100,7 @@ class MobileScanner(
97 100
98 if (newScannedBarcodes == lastScanned) { 101 if (newScannedBarcodes == lastScanned) {
99 // New scanned is duplicate, returning 102 // New scanned is duplicate, returning
  103 + imageProxy.close()
100 return@addOnSuccessListener 104 return@addOnSuccessListener
101 } 105 }
102 if (newScannedBarcodes.isNotEmpty()) { 106 if (newScannedBarcodes.isNotEmpty()) {
@@ -118,10 +122,12 @@ class MobileScanner( @@ -118,10 +122,12 @@ class MobileScanner(
118 } 122 }
119 123
120 if (barcodeMap.isEmpty()) { 124 if (barcodeMap.isEmpty()) {
  125 + imageProxy.close()
121 return@addOnSuccessListener 126 return@addOnSuccessListener
122 } 127 }
123 128
124 if (!returnImage) { 129 if (!returnImage) {
  130 + imageProxy.close()
125 mobileScannerCallback( 131 mobileScannerCallback(
126 barcodeMap, 132 barcodeMap,
127 null, 133 null,
@@ -130,31 +136,34 @@ class MobileScanner( @@ -130,31 +136,34 @@ class MobileScanner(
130 return@addOnSuccessListener 136 return@addOnSuccessListener
131 } 137 }
132 138
133 - val bitmap = Bitmap.createBitmap(mediaImage.width, mediaImage.height, Bitmap.Config.ARGB_8888)  
134 - val imageFormat = YuvToRgbConverter(activity.applicationContext) 139 + CoroutineScope(Dispatchers.IO).launch {
  140 + val bitmap = Bitmap.createBitmap(mediaImage.width, mediaImage.height, Bitmap.Config.ARGB_8888)
  141 + val imageFormat = YuvToRgbConverter(activity.applicationContext)
135 142
136 - imageFormat.yuvToRgb(mediaImage, bitmap) 143 + imageFormat.yuvToRgb(mediaImage, bitmap)
137 144
138 - val bmResult = rotateBitmap(bitmap, camera?.cameraInfo?.sensorRotationDegrees?.toFloat() ?: 90f) 145 + val bmResult = rotateBitmap(bitmap, camera?.cameraInfo?.sensorRotationDegrees?.toFloat() ?: 90f)
139 146
140 - val stream = ByteArrayOutputStream()  
141 - bmResult.compress(Bitmap.CompressFormat.PNG, 100, stream)  
142 - val byteArray = stream.toByteArray()  
143 - val bmWidth = bmResult.width  
144 - val bmHeight = bmResult.height  
145 - bmResult.recycle() 147 + val stream = ByteArrayOutputStream()
  148 + bmResult.compress(Bitmap.CompressFormat.PNG, 100, stream)
  149 + val byteArray = stream.toByteArray()
  150 + val bmWidth = bmResult.width
  151 + val bmHeight = bmResult.height
  152 + bmResult.recycle()
  153 + imageProxy.close()
  154 + mobileScannerCallback(
  155 + barcodeMap,
  156 + byteArray,
  157 + bmWidth,
  158 + bmHeight
  159 + )
  160 + }
146 161
147 - mobileScannerCallback(  
148 - barcodeMap,  
149 - byteArray,  
150 - bmWidth,  
151 - bmHeight  
152 - )  
153 }.addOnFailureListener { e -> 162 }.addOnFailureListener { e ->
154 mobileScannerErrorCallback( 163 mobileScannerErrorCallback(
155 e.localizedMessage ?: e.toString() 164 e.localizedMessage ?: e.toString()
156 ) 165 )
157 - }.addOnCompleteListener { imageProxy.close() } 166 + }
158 } 167 }
159 168
160 if (detectionSpeed == DetectionSpeed.NORMAL) { 169 if (detectionSpeed == DetectionSpeed.NORMAL) {