IO.Reactivex.CompositeDisposable de análisis de código fuente de Rxjava

El análisis del código fuente se basa en Rxjava3 en lugar de Rxjava2, existen diferencias sutiles entre los dos.
RxJava es propenso a pérdidas de memoria. En algunos casos, la falta de suscripción a tiempo provocará pérdidas de memoria. CompositeDisposable se dedica a la gestión de desechables.

CompositeDisposable es un recipiente desechable, que proporciona una variedad de métodos con la complejidad del tiempo del algoritmo O (1), como agregar, quitar, eliminar y otros métodos. La esencia es que existe una instancia de OpenHashSet con recursos dedicados a agregar y eliminar la administración Disposable.

Métodos principales en CompositeDisposable

  • 1. Dispose (), los recursos se dejan en blanco y cada Disposable in resources es Dispose uno por uno

  • 2. agregue (@NonNull Disposable desechable) y addAll (@NonNull Disposable desechable), agregue Disposable o su colección a los recursos, si se ha eliminado CompositeDisposable, el Disposable agregado eliminará y cancelará directamente la suscripción, y las tareas en Disposable no se pueden ejecutar.

  • 3. Quite (@NonNull Disposable desechable) y elimine (@NonNull Disposable desechable). El método remove esencialmente llama a delete, y un paso más es disposable.dispose (). Eliminar no solo elimina del contenedor los recursos, sino que también cancela la relación de conexión con el suscriptor después de que se ejecuta el desechable.

  • 4. claro (), deseche todos los recursos desechables contenidos en el contenedor

Nota sobre el uso de CompositeDisposable:

  • 该类中所有需要传Disposable的参数都不能为null,否则抛出NullPointerException
  • 一般在OnCreate中创建CompositeDisposable实例,在onDestory方法中进行clear()操作
  • 为了方便disposable 的管理,可以在Observer.onSubscribe(Disposable d)中将Disposable的实例加入CompositeDisposable中
       .subscribe(new Observer() {
          
          
                      @Override
                      public void onSubscribe(Disposable d) {
          
          
                          if(d!=null){
          
          
                              compositeDisposable.add(d);
                          }
                      }
    

El código fuente de CompositeDisposable es el siguiente:

public class IO_Reactivex_CompositeDisposable implements Disposable, DisposableContainer {
    
    

    /**
     * 存放 disposable 的 set
     */
    private OpenHashSet<Disposable> resources;

    /**
     * 是否已经处理过
     */
    private volatile boolean disposed;

    /**
     * Creates an empty {@code CompositeDisposable}.
     */
    public IO_Reactivex_CompositeDisposable() {
    
    
    }

    /**
     * Creates a {@code CompositeDisposable} with the given array of initial {@link Disposable} elements.
     * 创建 一个CompositeDisposable 通过给定的 初始元素数组。
     *
     * @param disposables the array of {@code Disposable}s to start with    起始的Disposables
     * @throws NullPointerException if {@code disposables} or any of its array items is {@code null} 如果存在一个disposable,则抛空异常
     */
    public IO_Reactivex_CompositeDisposable(@NonNull Disposable... disposables) {
    
    
        Objects.requireNonNull(disposables, "disposables is null");
        this.resources = new OpenHashSet<>(disposables.length + 1);
        for (Disposable d : disposables) {
    
    
            Objects.requireNonNull(d, "A Disposable in the disposables array is null");
            this.resources.add(d);
        }
    }

    /**
     * 创建 一个CompositeDisposable 通过给定的初始化元素 Iterable 序列
     * Creates a {@code CompositeDisposable} with the given {@link Iterable} sequence of initial {@link Disposable} elements.
     *
     * @param disposables the {@code Iterable} sequence of {@code Disposable} to start with   初始参数
     * @throws NullPointerException if {@code disposables} or any of its items is {@code null}   存在null 抛异常
     */
    public IO_Reactivex_CompositeDisposable(@NonNull Iterable<? extends Disposable> disposables) {
    
    
        Objects.requireNonNull(disposables, "disposables is null");
        this.resources = new OpenHashSet<>();
        for (Disposable d : disposables) {
    
    
            Objects.requireNonNull(d, "A Disposable item in the disposables sequence is null");
            this.resources.add(d);
        }
    }

    @Override
    public void dispose() {
    
    
        //已经处理过,不在调用
        if (disposed) {
    
    
            return;
        }
        OpenHashSet<Disposable> set;
        // 前面添加的OpenHashSet<Disposable> 清空,置null
        synchronized (this) {
    
    
            if (disposed) {
    
    
                return;
            }
            disposed = true;
            set = resources;
            resources = null;
        }

        dispose(set);
    }


    @Override
    public boolean isDisposed() {
    
    
        return disposed;
    }

    //TODO CompositeDisposable 的初始化,add 等方法中传入参数Disposable 或其数组都不可为null,否则抛空异常

    /**
     * TODO 添加一个Disposable 到 container容器中 ,如果container已经disposed,此时返回false且disposable.dispose();
     * Adds a {@link Disposable} to this container or disposes it if the
     * container has been disposed.
     *
     * @param disposable the {@code Disposable} to add, not {@code null}
     * @return {@code true} if successful, {@code false} if this container has been disposed
     * @throws NullPointerException if {@code disposable} is {@code null}
     */
    @Override
    public boolean add(@NonNull Disposable disposable) {
    
    
        Objects.requireNonNull(disposable, "disposable is null");
        if (!disposed) {
    
    
            synchronized (this) {
    
    
                if (!disposed) {
    
    
                    OpenHashSet<Disposable> set = resources;
                    // 刚刚初始化的CompositeDisposable,此时resources=null
                    if (set == null) {
    
    
                        set = new OpenHashSet<>();
                        resources = set;
                    }
                    set.add(disposable);
                    return true;
                }
            }
        }
        disposable.dispose();
        return false;
    }

    /**
     * 一次添加一个Disposable数组成功则返回true,如果容器disposed,则Disposable数组批量dispose此时返回false
     * Atomically adds the given array of {@link Disposable}s to the container or
     * disposes them all if the container has been disposed.
     *
     * @param disposables the array of {@code Disposable}s
     * @return {@code true} if the operation was successful, {@code false} if the container has been disposed
     * @throws NullPointerException if {@code disposables} or any of its array items is {@code null}
     */
    public boolean addAll(@NonNull Disposable... disposables) {
    
    
        Objects.requireNonNull(disposables, "disposables is null");
        if (!disposed) {
    
    
            synchronized (this) {
    
    
                if (!disposed) {
    
    
                    OpenHashSet<Disposable> set = resources;
                    if (set == null) {
    
    
                        set = new OpenHashSet<>(disposables.length + 1);
                        resources = set;
                    }
                    for (Disposable d : disposables) {
    
    
                        Objects.requireNonNull(d, "A Disposable in the disposables array is null");
                        set.add(d);
                    }
                    return true;
                }
            }
        }
        for (Disposable d : disposables) {
    
    
            d.dispose();
        }
        return false;
    }

    /**
     * TODO 如果disposable是resources中的一个,则从resources中移除,并且将该Disposable.dispose
     * Removes and disposes the given {@link Disposable} if it is part of this container.
     *
     * @param disposable the disposable to remove and dispose, not {@code null}
     * @return {@code true} if the operation was successful
     * @throws NullPointerException if {@code disposable} is {@code null}
     */
    @Override
    public boolean remove(@NonNull Disposable disposable) {
    
    
        if (delete(disposable)) {
    
    
            disposable.dispose();
            return true;
        }
        return false;
    }

    /**
     * TODO 从resources中移除Disposable,但不dispose。 如果resources=null,
     * TODO 或者resources.remove返回false,则该方法返回false
     * Removes (but does not dispose) the given {@link Disposable} if it is part of this container.
     *
     * @param disposable the disposable to remove, not {@code null}
     * @return {@code true} if the operation was successful
     * @throws NullPointerException if {@code disposable} is {@code null}
     */
    @Override
    public boolean delete(@NonNull Disposable disposable) {
    
    
        Objects.requireNonNull(disposable, "disposable is null");
        if (disposed) {
    
    
            return false;
        }
        synchronized (this) {
    
    
            if (disposed) {
    
    
                return false;
            }

            OpenHashSet<Disposable> set = resources;
            if (set == null || !set.remove(disposable)) {
    
    
                return false;
            }
        }
        return true;
    }

    /**
     * 原子性的清理container, 然后dispose 前面所有包含的Disposables
     * Atomically clears the container, then disposes all the previously contained {@link Disposable}s.
     */
    public void clear() {
    
    
        if (disposed) {
    
    
            return;
        }
        OpenHashSet<Disposable> set;
        synchronized (this) {
    
    
            if (disposed) {
    
    
                return;
            }

            set = resources;
            resources = null;
        }

        dispose(set);
    }

    /**
     * 返回 resources中的count
     * Returns the number of currently held {@link Disposable}s.
     *
     * @return the number of currently held {@code Disposable}s
     */
    public int size() {
    
    
        if (disposed) {
    
    
            return 0;
        }
        synchronized (this) {
    
    
            if (disposed) {
    
    
                return 0;
            }
            OpenHashSet<Disposable> set = resources;
            return set != null ? set.size() : 0;
        }
    }

    /**
     * TODO Dispose OpenHashSet中的元素 通过非致命的方式最后。  如果该过程中产生了异常,则抛出异常。
     * Dispose the contents of the {@link OpenHashSet} by suppressing non-fatal
     * {@link Throwable}s till the end.
     *
     * @param set the {@code OpenHashSet} to dispose elements of
     */
    private void dispose(@Nullable OpenHashSet<Disposable> set) {
    
    
        if (set == null) {
    
    
            return;
        }
        List<Throwable> errors = null;
        Object[] array = set.keys();
        for (Object o : array) {
    
    
            if (o instanceof Disposable) {
    
    
                try {
    
    
                    ((Disposable) o).dispose();
                } catch (Throwable ex) {
    
    
                    Exceptions.throwIfFatal(ex);
                    if (errors == null) {
    
    
                        errors = new ArrayList<>();
                    }
                    errors.add(ex);
                }
            }
        }
        if (errors != null) {
    
    
            if (errors.size() == 1) {
    
    
                throw ExceptionHelper.wrapOrThrow(errors.get(0));
            }
            throw new CompositeException(errors);
        }
    }
}

该篇博客纯属个人观点和见解,如有错误恳请留言指正,万分感激!

Enlace asociado:

Supongo que te gusta

Origin blog.csdn.net/luo_boke/article/details/105761725
Recomendado
Clasificación