2016-03-02 20 views
21

Tôi có câu hỏi liên quan đến cách hủy đăng ký một quan sát. Tôi có hai mã và tôi không thực sự chắc chắn về mã nào tốt hơn.Khi nào cần hủy đăng ký thuê bao

Ví dụ 1 -> Hủy đăng ký thuê bao một khi dòng đã hoàn tất:

Subscriber<String> subscriber = new Subscriber<String>() { 
     @Override 
     public void onCompleted() { 
      progressdialog.dissmiss(); 
      unsubscribe(); 
     } 

     @Override 
     public void onError(Throwable e) { 
      progressdialog.dissmiss(); 
     } 

     @Override 
     public void onNext(String s) { 
      // do something with data 
     } 
    } 

Ví dụ 2 -> Hủy đăng ký thuê bao một lần hoạt động này bị phá hủy:

private void test(){ 
    Subscriber<String> subscriber = new Subscriber<String>() { 
     @Override 
     public void onCompleted() { 
      progressdialog.dissmiss(); 
     } 

     @Override 
     public void onError(Throwable e) { 
      progressdialog.dissmiss(); 
     } 

     @Override 
     public void onNext(String s) { 
      // do something with data 
     } 
    }; 

    subscription = BackendRequest.login(loginRequest) 
      .subscribeOn(Schedulers.newThread()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(subscriber); 

    compositeSubscription.add(subscription); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    this.subscription.unsubscribe(); 
} 

tôi phải đề cập đến rằng tôi chỉ quan sát được sẽ phát ra một lần, hoạt động không nên đợi nhiều cuộc gọi hơn từ Đài quan sát.

Cái nào tốt hơn?

Cảm ơn trước

+0

Tôi gặp sự cố khi nhận mã của mình (có kéo để làm mới) để làm mới lần thứ hai khi sử dụng trình kéo để làm mới trình nghe. Tôi đã xác minh rằng kéo của tôi để làm mới là làm việc một cách chính xác nhưng tập thứ hai của "observable.subscribeOn (Schedulers.newThread()). ObservOn (AndroidSchedulers.mainThread()). Đăng ký (thuê bao)" không hoạt động, chỉ đầu tiên. Bất kỳ ý tưởng? – lawonga

Trả lời

21

Từ hai tùy chọn, tùy chọn thứ hai tốt hơn.

Trong ví dụ đầu tiên của bạn, bạn là unsubscribing trong phương pháp onComplete() không cần thiết. Nếu bạn đạt đến số onComplete() của Đăng ký, bạn không còn phải chịu trách nhiệm hủy đăng ký nữa.

Ví dụ thứ hai của bạn là ví dụ chính xác. Ý tưởng đằng sau CompositeSubscription là bạn có thể thêm nhiều Subscriptions vào nó và sau đó làm sạch (unsubscribe) cùng một lúc. Nói cách khác, điều này chỉ giúp bạn tiết kiệm được sự cần thiết phải giữ một danh sách Subscriptions mà bạn cần phải hủy đăng ký.

Một phần khó khăn khi sử dụng CompositeSubscription là nếu bạn một lần unsubscribe, bạn có thể NOT sử dụng lại. Bạn có thể kiểm tra tài liệu cho phương thức compositeSubscription.add() để biết chi tiết lý do. Tóm lại - nó sẽ trực tiếp hủy đăng ký Đăng ký bạn đang cố gắng thêm. Đó là một quyết định có chủ ý (bạn có thể đọc thêm về nó HERE).

Quay lại ví dụ của bạn, gọi unsubscribe() trong onDestroy() hoạt động là tốt và sẽ giúp bạn tiết kiệm từ rò rỉ bộ nhớ. Về nhận xét của bạn rằng các vấn đề xảy ra khi bạn gọi phương thức test() nhiều lần - tôi muốn nói vấn đề của bạn là ở một nơi khác. Có thể trường hợp sử dụng của bạn không được phép gọi nhiều lần, có thể bạn nên dọn dẹp dữ liệu cũ trước khi sử dụng dữ liệu mới nhận được, v.v. Có lẽ nếu bạn đã giải thích chi tiết về loại vấn đề bạn gặp phải, chúng tôi có thể trợ giúp nhiều hơn. Nhưng theo như các CompositeSubscription là có liên quan - bạn đang sử dụng nó và hủy đăng ký nó một cách chính xác!

+7

nhưng 'onDestroy' không được bảo đảm để được gọi. Nó có nghĩa là nếu 'onDestroy' không được gọi là vì một lý do nào đó sẽ có rò rỉ bộ nhớ vì' unsubscribe' không được gọi trong trường hợp này? – Storix

+0

Vì 'Observable' chỉ phát ra một mục, tại sao không sử dụng' Single' thay thế? Thay vì 'onNext()', nó gọi 'onSuccess()' SingleSubscriber' một lần, và sau đó nó được thực hiện (không có lệnh 'onComplete()'). –

3

Tôi nghĩ điều đó tùy thuộc vào nhu cầu của bạn. Nếu hoạt động không chờ cho bất kỳ cuộc gọi nào khác, tôi cho rằng bạn có thể hủy đăng ký bên trong onCompleted().

tôi luôn luôn bỏ đăng ký trong onDestroy()

@Override 
protected void onDestroy() { 
    super.onDestroy(); 

    if (subscription != null) { 
     subscription.unsubscribe(); 
    } 
} 

EDIT: hãy nhìn vào http://reactivex.io/RxJava/javadoc/rx/subscriptions/CompositeSubscription.html

private CompositeSubscription mCompositeSubscription = new CompositeSubscription(); 

private void doSomething() { 
    mCompositeSubscription.add(
     AndroidObservable.bindActivity(this, Observable.just("Hello, World!")) 
     .subscribe(s -> System.out.println(s))); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    mCompositeSubscription.unsubscribe(); 
} 
+0

Với ví dụ 2, bạn phải khai báo bao nhiêu đăng ký (biến thành viên) như những người bạn sử dụng trong hoạt động và trong Hủy bỏ hủy đăng ký tất cả, phải không? – MarcForn

+0

@MarcForn kiểm tra chỉnh sửa của tôi –

+0

Trong dự án của tôi, tôi đang sử dụng CompositeSubscription và bên trong phương pháp thử tôi thêm đăng ký vào CompositeSubscription. Vấn đề tôi đã tìm thấy (và đó là lý do của bài viết) là về gọi phương pháp thử nghiệm nhiều lần. Làm như vậy tôi nhận ra rằng chúng tôi có đăng ký n (giống nhau) được thêm vào danh sách CompositeSubscription. – MarcForn

24

Không cần phải để bỏ đăng ký trong onCompleted. Hãy nhìn vào The Observable Contract

Khi một vấn đề Quan sát một onerror hoặc thông báo onComplete để quan sát của nó, điều này kết thúc đăng ký. Các quan sát viên không cần phải gửi thông báo Hủy đăng ký để kết thúc đăng ký được kết thúc theo số Có thể quan sát theo cách này.

Mặt khác, bạn chắc chắn nên hủy đăng ký trong onDestroy để tránh rò rỉ bộ nhớ.

Các vấn đề liên quan