Kết quả của đăng ký không được sử dụng

138
Michael Dodd 2018-03-28 11:22.

Tôi đã nâng cấp lên Android Studio 3.1 hôm nay, có vẻ như đã thêm một số lần kiểm tra xơ vải. Một trong những cách kiểm tra lint này là dành cho các lệnh subscribe()gọi RxJava2 một lần không được lưu trữ trong một biến. Ví dụ: nhận danh sách tất cả người chơi từ cơ sở dữ liệu Phòng của tôi:

Single.just(db)
            .subscribeOn(Schedulers.io())
            .subscribe(db -> db.playerDao().getAll());

Kết quả là một khối lớn màu vàng và chú giải công cụ này:

Kết quả của subscribekhông được sử dụng

Cách thực hành tốt nhất cho các cuộc gọi Rx một lần như thế này là gì? Tôi có nên giữ lại Disposabledispose()hoàn thành không? Hay tôi chỉ nên @SuppressLinttiếp tục?

Điều này dường như chỉ ảnh hưởng đến RxJava2 ( io.reactivex), RxJava ( rx) không có xơ vải này.

7 answers

128
urgentx 2018-03-28 12:48.

IDE không biết đăng ký của bạn có thể có những tác động tiềm ẩn nào khi không được xử lý, vì vậy IDE coi đó là khả năng không an toàn. Ví dụ: của bạn Singlecó thể chứa một cuộc gọi mạng, có thể gây rò rỉ bộ nhớ nếu của bạn Activitybị bỏ qua trong quá trình thực thi.

Một cách thuận tiện để quản lý một lượng lớn Disposables là sử dụng CompositeDisposable ; chỉ cần tạo một CompositeDisposablebiến phiên bản mới trong lớp bao bọc của bạn, sau đó thêm tất cả các Vật liệu dùng một lần của bạn vào CompositeDisposable (với RxKotlin, bạn chỉ có thể thêm addTo(compositeDisposable)vào tất cả các Vật liệu dùng một lần của mình). Cuối cùng, khi bạn hoàn thành phiên bản của mình, hãy gọi compositeDisposable.dispose().

Điều này sẽ loại bỏ các cảnh báo xơ vải và đảm bảo của bạn Disposablesđược quản lý đúng cách.

Trong trường hợp này, mã sẽ giống như sau:

CompositeDisposable compositeDisposable = new CompositeDisposable();

Disposable disposable = Single.just(db)
        .subscribeOn(Schedulers.io())
        .subscribe(db -> db.get(1)));

compositeDisposable.add(disposable); //IDE is satisfied that the Disposable is being managed. 
disposable.addTo(compositeDisposable); //Alternatively, use this RxKotlin extension function.


compositeDisposable.dispose(); //Placed wherever we'd like to dispose our Disposables (i.e. in onDestroy()).
26
Aks4125 2018-03-29 00:56.

Thời điểm Hoạt động bị hủy, danh sách Đồ dùng một lần sẽ bị xóa và chúng tôi ổn.

io.reactivex.disposables.CompositeDisposable mDisposable;

    mDisposable = new CompositeDisposable();

    mDisposable.add(
            Single.just(db)
                    .subscribeOn(Schedulers.io())
                    .subscribe(db -> db.get(1)));

    mDisposable.dispose(); // dispose wherever is required
11
papandreus 2019-07-11 07:14.

Bạn có thể đăng ký với DisposableSingleObserver :

Single.just(db)
    .subscribeOn(Schedulers.io())
    .subscribe(new DisposableSingleObserver<Object>() {
            @Override
            public void onSuccess(Object obj) {
                // work with the resulting todos...
                dispose();
            }

            @Override
            public void onError(Throwable e) {
                // handle the error case...
                dispose();
            }});

Trong trường hợp bạn cần xử lý trực tiếp Singleđối tượng (ví dụ: trước khi nó phát ra), bạn có thể thực hiện phương thức onSubscribe(Disposable d)để lấy và sử dụng Disposabletham chiếu.

Bạn cũng có thể nhận ra SingleObservergiao diện của riêng bạn hoặc sử dụng các lớp con khác.

5
Eugene Popovich 2018-04-03 21:03.

Như đã đề xuất, bạn có thể sử dụng một số toàn cầu CompositeDisposableđể thêm kết quả của hoạt động đăng ký ở đó.

Các RxJava2Extensions thư viện chứa các phương pháp hữu ích để tự động loại bỏ được tạo ra dùng một lần từ CompositeDisposablekhi nó hoàn thành. Xem phần subscribeAutoDispose .

Trong trường hợp của bạn, nó có thể trông như thế này

SingleConsumers.subscribeAutoDispose(
    Single.just(db)
            .subscribeOn(Schedulers.io()),
    composite,
    db -> db.playerDao().getAll())
2
blaffie 2019-09-19 19:33.

Bạn có thể sử dụng Uber AutoDispose và rxjava.as

        Single.just(db)
            .subscribeOn(Schedulers.io())
            .as(AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(this)))
            .subscribe(db -> db.playerDao().getAll());

Đảm bảo rằng bạn hiểu khi bạn hủy đăng ký dựa trên ScopeProvider.

1
Dabbler 2020-04-25 13:07.

Một lần nữa tôi thấy mình quay trở lại câu hỏi làm thế nào để hủy đăng ký một cách chính xác và cụ thể là bài đăng này. Một số blog và các cuộc thảo luận cho rằng việc không gọi được disposenhất thiết dẫn đến rò rỉ bộ nhớ, mà tôi nghĩ đó là một tuyên bố quá chung chung. Theo hiểu biết của tôi, cảnh báo lint về việc không lưu trữ kết quả subscribelà không phải là vấn đề trong một số trường hợp, bởi vì:

  • Không phải tất cả các thiết bị có thể quan sát đều chạy trong bối cảnh hoạt động của Android
  • Có thể quan sát được đồng bộ
  • Loại bỏ được gọi là ngầm định, miễn là việc hoàn thành có thể quan sát được

Vì tôi không muốn loại bỏ cảnh báo xơ vải nên gần đây tôi đã bắt đầu sử dụng mẫu sau cho các trường hợp có thể quan sát đồng bộ:

var disposable: Disposable? = null

disposable = Observable
   .just(/* Whatever */)
   .anyOperator()
   .anyOtherOperator()
   .subscribe(
      { /* onSuccess */ },
      { /* onError */ },
      {
         // onComplete
         // Make lint happy. It's already disposed because the stream completed.
         disposable?.dispose()
      }
   )

Tôi muốn quan tâm đến bất kỳ nhận xét nào về điều này, bất kể đó là xác nhận tính đúng đắn hay phát hiện ra sơ hở.

0
Fernando Prieto 2020-05-19 07:12.

Có một cách khác có sẵn, đó là tránh sử dụng Đồ dùng một lần theo cách thủ công (thêm và xóa đăng ký).

Bạn có thể định nghĩa một Observable và có thể quan sát sẽ nhận nội dung từ SubjectBehaviour (trong trường hợp bạn sử dụng RxJava). Và bằng cách chuyển dữ liệu có thể quan sát được sang LiveData của bạn , điều đó sẽ hoạt động. Xem ví dụ tiếp theo dựa trên câu hỏi ban đầu:

private val playerSubject: Subject<Player> = BehaviorSubject.create()

private fun getPlayer(idPlayer: String) {
        playerSubject.onNext(idPlayer)
}

private val playerSuccessful: Observable<DataResult<Player>> = playerSubject
                        .flatMap { playerId ->
                            playerRepository.getPlayer(playerId).toObservable()
                        }
                        .share()

val playerFound: LiveData<Player>
    get() = playerSuccessful
        .filterAndMapDataSuccess()
        .toLiveData()

val playerNotFound: LiveData<Unit>
    get() = playerSuccessful.filterAndMapDataFailure()
        .map { Unit }
        .toLiveData()

// These are a couple of helpful extensions

fun <T> Observable<DataResult<T>>.filterAndMapDataSuccess(): Observable<T> =
filter { it is DataResult.Success }.map { (it as DataResult.Success).data }

fun <T> Observable<DataResult<T>>.filterAndMapDataFailure(): Observable<DataResult.Failure<T>> =
filter { it is DataResult.Failure }.map { it as DataResult.Failure<T> }

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Tận dụng lợi thế của việc bán hàng nhân Ngày của Cha này

Tận dụng lợi thế của việc bán hàng nhân Ngày của Cha này

Màn hình Samsung Galaxy S9 Plus. Chủ nhật này là Ngày của Cha⁠ — trong trường hợp nó khiến bạn suy nghĩ — và thay vì mua cho anh ấy một chiếc cà vạt trong năm nay, có lẽ đã đến lúc bạn mua cho anh ấy thứ mà anh ấy sẽ thực sự sử dụng.

Assassin's Creed Snuck Into Monster Hunter: World Last Night

Assassin's Creed Snuck Into Monster Hunter: World Last Night

Monster Hunter: World yêu thích các sự kiện chéo. Dù có nghĩa là hóa trang thành Dante của Devil May Cry, giả dạng Horizon: Zero Dawn's Aloy, hay chiến đấu với quái vật Final Fantasy, các nhiệm vụ sự kiện khác nhau của Thế giới được nâng cấp tự do so với các trò chơi khác.

Ava DuVernay Có Quà Tặng Ngày Của Mẹ cho Tất Cả Chúng Ta: Nếp Nhăn Thời Gian Sẽ Được Viết Lại Vào Cuối Tuần Ngày Của Mẹ!

Ava DuVernay Có Quà Tặng Ngày Của Mẹ cho Tất Cả Chúng Ta: Nếp Nhăn Thời Gian Sẽ Được Viết Lại Vào Cuối Tuần Ngày Của Mẹ!

Storm Reid, Oprah Winfrey, Mindy Kaling, Reese Witherspoon và Ava DuVernay tại buổi chiếu đặc biệt của A Wrinkle in Time tại Nhà hát Walter Reade ở Thành phố New York vào ngày 7 tháng 3 năm 2018 “Ava rất mong được nói chuyện với bạn,” một trong những người của Array dư luận viên nói qua điện thoại. (Array là tập thể phân phối, nghệ thuật và vận động chính sách của Ava DuVernay tập trung vào các bộ phim của người da màu và phụ nữ.

Nhiệm vụ bất khả thi 5 sẽ khôi phục niềm tin của bạn trong phim hành động Tentpole

Nhiệm vụ bất khả thi 5 sẽ khôi phục niềm tin của bạn trong phim hành động Tentpole

Mission Impossible: Rogue Nation bắt đầu ở một cấp độ khác. Theo nghĩa đen.

Edwin McCain ra mắt Grand Ole Opry: Quay cảnh hậu trường với nhạc sĩ 'I'll Be'

Edwin McCain ra mắt Grand Ole Opry: Quay cảnh hậu trường với nhạc sĩ 'I'll Be'

McCain, người đang làm việc cho một album mới, lần đầu tiên bước vào vòng kết nối vào tối thứ Sáu ở Nashville

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Tôi viết như thế nào

Tôi viết như thế nào

Đối với tôi, mọi thứ là về dòng đầu tiên đó và nó sẽ đưa bạn đến đâu. Một số nhà văn bị điều khiển bởi cốt truyện, sự sắp xếp tinh tế của các quân cờ, trong khi những người khác bị lôi cuốn bởi một nhân vật và khả năng thực hiện một cuộc hành trình với một người bạn hư cấu mới.

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Language