0

Một số bugs và tips thường gặp trong Android

1. Dùng HttpURLConnection

  • Khi dùng HttpURLConnection để connect tới một URL thì lưu ý, URL mình dùng phải là "https". Ở đây, mình dùng để mở đường dẫn tải audio từ một link.
 private fun download(url: String) {
        var exception: Exception? = null
        var fos: FileOutputStream? = null
        var myPath: File? = null
        var connection: HttpURLConnection? = null
        var input: BufferedInputStream? = null

        try {
            myPath = File("audios", "home.mp3")
            if (!myPath.exists()) {
                connection = URL(url).openConnection() as HttpURLConnection
                connection.connect()
                input = BufferedInputStream(URL(url).openStream())
                fos = FileOutputStream(myPath)
                val data = ByteArray(LessonTopicFragment.SIZE_BYTE)
                var count: Int = input.read(data)
                while (count != -1) {
                    fos.write(data, 0, count)
                    count = input.read(data)
                }
            }
        } catch (e: Exception) {
            exception = e
        } finally {
            fos?.flush()
            fos?.close()
            input?.close()
            connection?.disconnect()
        }
    }

Lưu ý: Trong file Android.Manifest cần khai báo thêm thuộc tính : android:usesCleartextTraffic="true" trong thẻ application.

Trong hàm download trên, nếu như truyền vào một url với "http" thì sẽ vẫn download được file, nhưng có một bug ở đây đó là ta chỉ down được đúng một lần với lượng data bằng biến count. Khi thay http sang https thì ta down được file hoàn chỉnh.

2. Dùng ListAdapter

  • Khi dùng với ListAdapter thì muốn cập nhật được list một cách chính xác nhất nên tạo một list mới với data đã được cập nhật rồi, và submit lits mới đó. khi dùng với ListAdapter thì kể cả có gọi notify data cũng không thể update được UI.

3. Type Any hoặc List trong Kotlin

Khi sử dụng các type Any hoặc List trong Kotlin, có thể sẽ gặp exception này:

java.lang.IllegalArgumentException: Parameter type must not include a type variable or wildcard

Ví dụ khi POST một trường như sau bằng Retrofit, sẽ gặp exception phía trên:

@POST("speech/practice")
@FormUrlEncoded
fun uploadLog(
   @Field("alignment") alignment: List<List<Float>>? = null
)

Lí do vì khi compile Kotlin đã chuyển các type này về kiểu wildcard ? nên JVM không cho phép dùng làm param

Ví dụ khi compile, biến alignment sẽ chuyển thành kiểu

List<? extends List<Float>>

Để khắc phục, mọi người chỉ cần thêm @JvmSuppressWildcards vào phía trước nơi định kiểu, hàm, hoặc class đều được (tất nhiên mỗi nơi có scope khác nhau)

@Field("alignment") alignment: List<@JvmSuppressWildcards List<Float>>? = null

Link tham khảo: https://stackoverflow.com/questions/45409461/the-generic-parameters-any-of-kotlin-are-converted-to-wildcards https://adavis.info/2017/08/jvmsuppresswildcards-biggest-annoyance-kotlin.html

4. Index trong List

Khi làm việc với list trong 1 số trường hợp có thể muốn get phần thử theo index nhưng không chắc index đó có nằm trong range của list hay không. Thường thi ta sẽ check bằng if else, hơi dài 1 tí. Để ngắn gọn hơn thì Kotlin đã hỗ trợ ta với hàm có sẵn getOrNull(index)

val list = ArrayList<String>()
val t = list.getOrNull(2)

output: t = null vì list không có phần tử index = 2

5. Unit test

Khi viết UT có case này khả năng gây lỗi mọi người tham khảo để tránh nhé:

  • Nếu test cho ViewModel mà có dùng fun init() thì trong class test phải mock cho các phần cần thiết trước khi khởi tạo đối tượng vm. (thường là làm trong fun @before)
  • Vì khi khởi tạo vm, fun được dùng trong init() sẽ chạy luôn và gây lỗi NullPointer.

Cảm ơn mọi người đã đón đọc !


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí