Lưu lượng Kotlin vs LiveData


10

Trong Google I / O cuối cùng, Jose Alcerreca và Yigit Boyar nói với chúng tôi rằng chúng ta không còn nên sử dụng LiveData để lấy dữ liệu. Bây giờ chúng ta nên sử dụng các chức năng treo cho các lần tìm nạp một lần và sử dụng Flow của Kotlin để tạo luồng dữ liệu. Tôi đồng ý rằng coroutines rất tốt cho tìm nạp một lần hoặc các thao tác CRUD khác, chẳng hạn như chèn, v.v. Nhưng trong trường hợp tôi cần một luồng dữ liệu, tôi không hiểu những lợi thế mà Flow mang lại cho tôi. Dường như với tôi rằng LiveData cũng đang làm như vậy.

Ví dụ với Flow:

ViewModel

val items = repository.fetchItems().asLiveData()

Kho

fun fetchItems() = itemDao.getItems()

Đào

@Query("SELECT * FROM item")
fun getItems(): Flow<List<Item>>

Ví dụ với LiveData:

ViewModel

val items = repository.fetchItems()

Kho

fun fetchItems() = itemDao.getItems()

Đào

@Query("SELECT * FROM item")
fun getItems(): LiveData<List<Item>>

Tôi cũng muốn xem một số ví dụ về các dự án sử dụng coroutines và Flow để làm việc với Room hoặc Retrofit. Tôi chỉ tìm thấy một mẫu ToDo của Google trong đó coroutines được sử dụng để tìm nạp một lần và sau đó lấy lại dữ liệu theo cách thủ công khi thay đổi.

Câu trả lời:


3

Flowlà một loại reactive stream(như rxjava). Có một loạt các toán tử khác nhau .map, buffer()(dù sao thì ít hơn. Của toán tử so với rxJava). Vì vậy, một trong những khác biệt chính giữa LiveDataFlowlà bạn có thể đăng ký bản đồ computation / transformationtrong một số chủ đề khác bằng cách sử dụng

 flowOn(Dispatcher....). 

Vì vậy, ví dụ: -

 flowOf("A","B","C").map { compute(it) }.flowOn(Dispatchers.IO).collect {...} // U can change the execution thread of the computation ( by default its in the same dispatcher as collect )

Với LiveDatamap, không thể đạt được ở trên!

Vì vậy, nó được khuyến nghị để giữ dòng chảy ở cấp kho lưu trữ và làm cho liveata trở thành cầu nối giữa UI và kho lưu trữ!

Sự khác biệt chính là flowcó một loạt các nhà khai thác khác nhau mà livedatakhông có! Nhưng một lần nữa, bạn muốn xây dựng dự án của mình như thế nào!


3

Như tên cho thấy, bạn có thể nghĩ về Flow giống như một luồng liên tục gồm nhiều giá trị được tính toán không đồng bộ. Sự khác biệt chính giữa LiveData và Flow, theo quan điểm của tôi, là Flow liên tục phát ra kết quả trong khi LiveData sẽ cập nhật khi tất cả dữ liệu được tìm nạp và trả về tất cả các giá trị cùng một lúc. Trong ví dụ của bạn, bạn đang tìm nạp các giá trị đơn lẻ, đó không chính xác là dòng chảy được tạo ra theo ý kiến ​​của tôi.

Tôi không có ví dụ về Phòng nhưng giả sử bạn đang hiển thị thứ gì đó mất thời gian, nhưng bạn muốn hiển thị kết quả trong khi hiển thị và đệm kết quả tiếp theo.

private fun render(stuffToPlay: List<Any>): Flow<Sample> = flow {
     val sample = Sample()
     // computationally intensive operation on stuffToPlay
     Thread.sleep(2000)
     emit(sample)
}

Sau đó, trong chức năng 'Phát lại', bạn có thể hiển thị kết quả trong đó StuffToPlay là Danh sách các đối tượng sẽ hiển thị, như:

playbackJob = GlobalScope.launch(Dispatchers.Default) {

    render(stuffToPlay)
        .buffer(1000)   // tells the Flow how many values should be calculated in advance

        .onCompletion {
            // gets called when all stuff got played
        }
        .collect{sample ->
           // collect the next value in the buffered queue
           // e.g. display sample
        }
}

Một đặc điểm quan trọng của Flow là mã trình tạo của nó (ở đây là chức năng kết xuất) chỉ được thực thi, khi nó được thu thập, do đó là một luồng lạnh .

Bạn cũng có thể tham khảo các tài liệu tại Luồng không đồng bộ

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.