সাবস্ক্রাইব ফলাফল ব্যবহার করা হয় না


133

আমি আজ অ্যান্ড্রয়েড স্টুডিও ৩.১ এ আপগ্রেড করেছি, যা দেখে মনে হচ্ছে আরও কয়েকটি লিঙ্ক চেক যুক্ত হয়েছে। এই লিন্ট চেকগুলির subscribe()মধ্যে একটি হ'ল এক-শট আরএক্সজেভা 2 কলগুলির জন্য যা কোনও ভেরিয়েবলে সঞ্চয় করা হয় না। উদাহরণস্বরূপ, আমার রুম ডাটাবেস থেকে সমস্ত খেলোয়াড়ের একটি তালিকা পাওয়া:

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

একটি বড় হলুদ ব্লক এবং এই সরঞ্জামদণ্ডের ফলাফল:

ফলাফল subscribeব্যবহার করা হয় না

অ্যান্ড্রয়েড স্টুডিওর স্ক্রিনশট।  কোডটি একটি টুলটিপ দিয়ে হলুদে হাইলাইট করা হয়েছে।  টুলটিপ পাঠ্য: সাবস্ক্রাইব ফলাফল ব্যবহার করা হয় না।

এই জাতীয় ওয়ান-শট আরএক্স কলগুলির জন্য সেরা অনুশীলন কী? আমি ধরে রাখা উচিত Disposableএবং dispose()সম্পূর্ণ উপর? না আমার কি কেবল @SuppressLintএগিয়ে যাওয়া উচিত ?

এটি কেবল RxJava2 ( io.reactivex) কে প্রভাবিত করে বলে মনে হচ্ছে , আরএক্সজেভা ( rx) এর এই লিঙ্ক নেই।


আপনার উভয় সমাধানের মধ্যে, আমি সত্যই বলেছি যে @ সাপ্রেসলিঙ্কটি সর্বোত্তম নয়। হতে পারে আমি ভুল কিন্তু আমি সত্যিই মনে করি কোডটি কখনই আইডিইর সতর্কতা এবং / বা ইঙ্গিতগুলিতে কোনও পরিবর্তন করা উচিত নয়
আর্থার অ্যাটুট

@ আর্থার অ্যাটআউট সম্মত, বর্তমানে আমি Disposableসদস্যের স্কোপ ধরে রেখেছি এবং dispose()এককটি সম্পূর্ণ হওয়ার পরে ফোন করছি, তবে এটি অযথা জটিল মনে হচ্ছে। আমি এটি করার আরও ভাল উপায় আছে কিনা তা দেখতে আগ্রহী।
মাইকেল ডড

8
আমার মনে হয় যখন কোনও ক্রিয়াকলাপ / খণ্ড / ভিউমোডেলের মধ্যে আরএক্সজাভা স্ট্রিম সাবস্ক্রাইব না হয়ে থাকে তখন এই লিঙ্ক সতর্কতা বিরক্তিকর। আমার কাছে একটি কমপিটেবল রয়েছে যা ক্রিয়াকলাপের জীবনচক্রের কোনও বিবেচনা ছাড়াই নিরাপদে চলতে পারে, তবুও আমার এখনও এটি নিষ্পত্তি করতে হবে?
EM

RxLifecycle বিবেচনা করুন
3

উত্তর:


122

আপনার সাবস্ক্রিপশনটি নিষ্পত্তি না করা হলে কী সম্ভাব্য প্রভাব পড়তে পারে তা IDE জানে না, সুতরাং এটি এটিকে সম্ভাব্য অনিরাপদ হিসাবে বিবেচনা করে। উদাহরণস্বরূপ, আপনার Singleএকটি নেটওয়ার্ক কল থাকতে পারে, যা Activityকার্যকর করার সময় আপনার যদি পরিত্যক্ত হয় তবে মেমরি ফাঁস হতে পারে ।

প্রচুর পরিমাণে পরিচালনা করার একটি সুবিধাজনক উপায় Disposableহ'ল কমপোজাইটডিস্পোজেবল ব্যবহার করা ; CompositeDisposableআপনার ঘেরের ক্লাসে কেবল একটি নতুন উদাহরণের পরিবর্তনশীল তৈরি করুন, তারপরে আপনার সমস্ত ডিসপোজেবলগুলি কমপোজিট ডিসপোজেবলের সাথে যুক্ত করুন (আরএক্সকোটলিনের সাহায্যে আপনি কেবল addTo(compositeDisposable)আপনার সমস্ত ডিসপোজেবলগুলিতে সংযোজন করতে পারেন )। অবশেষে, আপনি যখন আপনার উদাহরণটি সম্পন্ন করবেন তখন কল করুন compositeDisposable.dispose()

এটি লিন্টের সতর্কতাগুলি থেকে মুক্তি পাবে এবং আপনার Disposablesসঠিকভাবে পরিচালিত হয়েছে তা নিশ্চিত করবে ।

এই ক্ষেত্রে, কোডটি দেখতে এমন হবে:

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()).

আমি error: cannot find symbol method addTo(CompositeDisposable)"rxjava: 2.1.13" দিয়ে সংকলন ত্রুটি পাচ্ছি। এই পদ্ধতিটি কোথা থেকে আসে? (আরএক্সসুইফ্ট বা আরএক্সকোটলিন আমি মনে করি)
আয়েরাকোড

2
হ্যাঁ, এটি একটি আরএক্সকোটলিন পদ্ধতি।
তাত্ক্ষণিক

1
প্রবাহের ক্ষেত্রে কী করবেন
হান্ট

যদি আমরা doOnSubscribe এই করছেন
হত্যাকারী

2
এটি কোনও স্মৃতি ফাঁস হতে পারে না। একবার নেটওয়ার্ক কল শেষ হয়ে গেলে এবং অনম্পল্ট কল হয়ে গেলে, আবর্জনা সংগ্রহ বাকিগুলির সাথে মোকাবিলা করবে যদি না আপনি ডিসপোজেবলের স্পষ্ট উল্লেখ রেখে থাকেন এবং তা নিষ্পত্তি না করেন।
গ্যাব্রিয়েল

26

কার্যকলাপটি ধ্বংস হয়ে যাওয়ার সাথে সাথে ডিস্পোজেবলের তালিকা সাফ হয়ে যায় এবং আমরা ভাল।

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

9

আপনি ডিসপোজেবলসিংঅলবার্সের সাথে সদস্যতা নিতে পারেন :

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();
            }});

আপনার যদি সরাসরি Singleঅবজেক্টটি নিষ্পত্তি করতে হয় (উদাহরণস্বরূপ এটি বের হওয়ার আগে) আপনি রেফারেন্সটি onSubscribe(Disposable d)পেতে এবং ব্যবহারের জন্য পদ্ধতিটি প্রয়োগ করতে পারেন Disposable

আপনি SingleObserverনিজের দ্বারা ইন্টারফেস উপলব্ধি করতে পারেন বা অন্যান্য শিশু ক্লাস ব্যবহার করতে পারেন।


5

প্রস্তাবিত হিসাবে আপনি কিছু CompositeDisposableসাবস্ক্রাইব অপারেশন ফলাফল যোগ করতে কিছু গ্লোবাল ব্যবহার করতে পারেন ।

RxJava2Extensions লাইব্রেরিতে স্বয়ংক্রিয়ভাবে থেকে নিষ্পত্তিযোগ্য নির্মিত সরিয়ে দরকারী পদ্ধতি রয়েছে CompositeDisposableযখন এটি সমাপ্ত হবে। সাবস্ক্রাইবআউটো ডিসপোজ বিভাগটি দেখুন ।

আপনার ক্ষেত্রে এটি দেখতে এটি দেখতে পারে

SingleConsumers.subscribeAutoDispose(
    Single.just(db)
            .subscribeOn(Schedulers.io()),
    composite,
    db -> db.playerDao().getAll())

2

আপনি উবার অটোডিসপস এবং আরএক্সজাভা ব্যবহার করতে পারেন.as

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

আপনি যখন স্কোপপ্রাইডারের উপর ভিত্তি করে সাবস্ক্রাইব করেন তখন নিশ্চিত হয়ে গেছেন।


এটি ধরে নিয়েছে একটি জীবনচক্র সরবরাহকারী উপলব্ধ। এছাড়াও, "হিসাবে" পদ্ধতিটি অস্থির হিসাবে চিহ্নিত করা হয়েছে, সুতরাং এটি ব্যবহারের ফলে লিন্টের সতর্কতা হবে।
ডাবলারের

1
ধন্যবাদ @ ড্যাবলার, একমত হয়েছেন। .As পদ্ধতি RxJava 2.1.7 পর্যন্ত পরীক্ষামূলক ছিল এবং 2.2 তে এটি এর স্থিতিশীল।
বেলফি

1

বারবার আমি নিজেকে সাবস্ক্রিপশনগুলি কীভাবে সঠিকভাবে নিষ্পত্তি করতে হবে এবং বিশেষত এই পোস্টিংয়ে ফিরে এসেছি। বেশ কয়েকটি ব্লগ এবং আলোচনায় দাবি করা হয়েছে যে disposeঅগত্যা কল করতে ব্যর্থ হওয়া স্মৃতি ফাঁসির দিকে পরিচালিত করে, যা আমি মনে করি এটি খুব সাধারণ বিবৃতি। আমার বোধে, ফলাফলটি সংরক্ষণ না করার বিষয়ে জিন্টের সতর্কতা subscribeকিছু ক্ষেত্রে নন-ইস্যু, কারণ:

  • সমস্ত পর্যবেক্ষণযোগ্য কোনও অ্যান্ড্রয়েড ক্রিয়াকলাপের প্রসঙ্গে চালিত হয় না
  • পর্যবেক্ষণযোগ্য সিনক্রোনাস হতে পারে
  • নিষ্পত্তি সম্পূর্ণরূপে বলা হয়, পর্যবেক্ষণযোগ্য সম্পূর্ণ হলে provided

যেহেতু আমি লিন্টের সতর্কতাগুলি দমন করতে চাই না আমি সম্প্রতি একটি সিঙ্ক্রোনাস পর্যবেক্ষণযোগ্য ক্ষেত্রে নিম্নলিখিত প্যাটার্নগুলি ব্যবহার করতে শুরু করেছি:

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()
      }
   )

আমি এ সম্পর্কে কোনও মন্তব্যে আগ্রহী হব, তা নির্বিশেষে এটি নির্ভুলতার নিশ্চয়তা হোক বা একটি ফাঁক আবিষ্কারটি হোক।


0

আর একটি উপায় উপলভ্য আছে, যা ম্যানুয়ালি ডিসপোজেবলগুলি ব্যবহার করা এড়ানো হচ্ছে (সাবস্ক্রিপশন যুক্ত এবং সরিয়ে ফেলুন)।

আপনি একটি পর্যবেক্ষণযোগ্যকে সংজ্ঞায়িত করতে পারেন এবং এটি পর্যবেক্ষণযোগ্য সাবজেক্টবিহাভিওর (যদি আপনি আরএক্সজাভা ব্যবহার করেন) থেকে সামগ্রী পেতে চলেছে। এবং আপনার লাইভডাটাতে এটি পর্যবেক্ষণযোগ্য পাস করে , এটি কাজ করা উচিত। প্রাথমিক প্রশ্নের উপর ভিত্তি করে পরবর্তী উদাহরণটি দেখুন:

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> }

-10

আপনি যদি নিশ্চিত হন যে ডিসপোজেবল সঠিকভাবে পরিচালিত হয়েছে, উদাহরণস্বরূপ doOnSubscribe () অপারেটর ব্যবহার করে, আপনি এটিকে গ্রেডলে যুক্ত করতে পারেন:

android {
lintOptions {
     disable 'CheckResult'
}}

10
এটি একটি চেক না হওয়া ফলাফলের সমস্ত দৃষ্টান্তের জন্য এই লিন্ট চেকটি দমন করবে। ওপি-র উদাহরণের বাইরে প্রচুর সময় রয়েছে যাতে কোনও ব্যক্তির ফিরে আসা ফলাফলটি পরিচালনা করা উচিত। এটি একটি উড়ে মারার জন্য স্লেজহ্যামার ব্যবহার করছে।
tir38

16
দয়া করে এটি করবেন না! আপনি এই সতর্কতাগুলি পাওয়ার একটি কারণ রয়েছে। আপনি কী করছেন তা যদি জানেন (এবং জানেন যে আপনার সত্যিকারের সাবস্ক্রিপশনটি নিষ্পত্তি করার দরকার নেই) আপনি @SuppressLint("CheckResult")কেবল পদ্ধতিতে দমন করতে পারেন ।
ভিক্টর রেন্ডিনা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.