Android 开发技术分享Android开发Android开发学习

Retrofit结合Lifecycle, 将Http生命周期管理

2019-08-27  本文已影响0人  xcheng_
http请求一直是开发中无法避免的存在,生命周期的管理也一直是开发者的痛点,稍不注意就在回调是抛出异常,如NullPointerException,showDialog导致的WindowLeaked等。

Google 最新推荐的 Lifecycle 架构就是可以让你自己的类拥有像 activity 或 fragment 一样生命周期的功能。

于是我决定采用lifecycle结合retrofit 将http请求和Activity或Fragment的生命周期相结合

本文将从以下几个方面一步步实现功能

如果有不熟悉lifecycle的可以自行学习,这里不做介绍了

lifecycle官方文档地址:https://developer.android.com/topic/libraries/architecture/lifecycle

为什么要使用lifecycle?

activity 和fragment 是有声明周期的,有时候,我们的很多操作需要写在声明周期的方法中,比如,下载,文件操作等,这样很多情况下回导致,我们在activity中的声明周期方法中写越来越多的代码,activity或者fragment 越来越臃肿,代码维护越来越困难。 使用lifecycle就可以很好的解决这类问题。
lifecycle代码简洁,我们可以通过实现LifecycleObserver 接口,来监听声明周期,然后我们在activity和fragment中去注册监听。

一 、分发lifecycle event

对于event的分发我们采用观察者模式,需要支持多线程环境,因为http请求可能在任意线程中发起。

首先定义一个 LifecycleProvider类,如下

/**
 * 统一分发Activity和 Fragment的生命周期时间.
 */
public interface LifecycleProvider {
    /**
     * Adds an observer to the list. The observer cannot be null and it must not already
     * be registered.
     *
     * @param observer the observer to register
     * @throws IllegalArgumentException the observer is null
     */
    void observe(Observer observer);

    /**
     * Removes a previously registered observer. The observer must not be null and it
     * must already have been registered.
     *
     * @param observer the observer to unregister
     * @throws IllegalArgumentException the observer is null
     */
    void removeObserver(Observer observer);

    /**
     * A simple callback that can receive from {@link android.arch.lifecycle.Lifecycle}
     */
    interface Observer {
        /**
         * Called when the event is changed.
         *
         * @param event The new event
         */
        void onChanged(@NonNull Lifecycle.Event event);
    }
}

实现类 为AndroidLifecycle 继承了LifecycleObserver接口监听Lifecycle event

public final class AndroidLifecycle implements LifecycleProvider, LifecycleObserver {
    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private final ArrayList<Observer> mObservers = new ArrayList<>();
    /**
     * 缓存当前的Event事件
     */
    @GuardedBy("mLock")
    @Nullable
    private Lifecycle.Event mEvent;

    @MainThread
    public static LifecycleProvider createLifecycleProvider(LifecycleOwner owner) {
        return new AndroidLifecycle(owner);
    }

    private AndroidLifecycle(LifecycleOwner owner) {
        owner.getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    void onEvent(LifecycleOwner owner, Lifecycle.Event event) {
        synchronized (mLock) {
            //保证线程的可见性
            mEvent = event;
            for (int i = mObservers.size() - 1; i >= 0; i--) {
                mObservers.get(i).onChanged(event);
            }
        }
        if (event == Lifecycle.Event.ON_DESTROY) {
            owner.getLifecycle().removeObserver(this);
        }
    }

    @Override
    public void observe(Observer observer) {
        if (observer == null) {
            throw new IllegalArgumentException("The observer is null.");
        }
        synchronized (mLock) {
            if (mObservers.contains(observer)) {
                return;
            }
            mObservers.add(observer);
            if (mEvent != null) {
                observer.onChanged(mEvent);
            }
        }
    }

    @Override
    public void removeObserver(Observer observer) {
        if (observer == null) {
            throw new IllegalArgumentException("The observer is null.");
        }
        synchronized (mLock) {
            int index = mObservers.indexOf(observer);
            if (index == -1) {
                return;
            }
            mObservers.remove(index);
        }
    }
}

使用时只要在onChanged方法中就可以处理对应的事件,使用如下

    LifecycleProvider provider = AndroidLifecycle.createLifecycleProvider(this);
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        provider.observe(new LifecycleProvider.Observer() {
            @Override
            public void onChanged(@NonNull Lifecycle.Event event) {
                //do...
            }
        });
    }

observe方法不依赖于主线程,可以在任何地方调用。这样二次分发设计的目的有两个

二、retrofit 关联生命周期

​ retrofit 如何才能关联生命周期呢,通用的做法肯定是自定义CallAdapter.Factory,我们可以返回我们想要的自定义Call,在Call接口添加bindToLifecycle方法于LifecycleProvider相关联

public interface Call<T> extends Callable<T>, Cloneable {
          //忽略其他代码
    /**
     * 绑定生命周期
     *
     * @param provider LifecycleProvider
     * @param event    {@link Lifecycle.Event}, {@link Lifecycle.Event#ON_ANY} is not allowed
     * @return LifeCall
     */
    LifeCall<T> bindToLifecycle(LifecycleProvider provider, Lifecycle.Event event);

    /**
     * default event is {@link Lifecycle.Event#ON_DESTROY}
     *
     * @param provider LifecycleProvider
     * @return LifeCall
     * @see Call#bindToLifecycle(LifecycleProvider, Lifecycle.Event)
     */
    LifeCall<T> bindUntilDestroy(LifecycleProvider provider);
}

retrofit的解耦灵活我们可以做很多自定义的配置,自定义Factory返回我们的Call接口对象,只需在创建retrofit对象是调用addCallAdapterFactory(CallAdapterFactory.INSTANCE)添加进去即可。

注:executor默认为Android主线程调度使用,Callback回调函数会在对应线程执行。详情可以看retrofit2.Platform.Android.defaultCallbackExecutor()方法

public final class CallAdapterFactory extends CallAdapter.Factory {
    private static final String RETURN_TYPE = Call.class.getSimpleName();

    public static final CallAdapter.Factory INSTANCE = new CallAdapterFactory();

    private static final Executor OPTIONAL_NULL_EXECUTOR = new Executor() {
        @Override
        public void execute(@NonNull Runnable command) {
            command.run();
        }
    };

    private CallAdapterFactory() {
    }
    
    @Override
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        if (getRawType(returnType) != Call.class) {
            return null;
        }
        if (!(returnType instanceof ParameterizedType)) {
            throw new IllegalArgumentException(
                    String.format("%s return type must be parameterized as %s<Foo> or %s<? extends Foo>", RETURN_TYPE, RETURN_TYPE, RETURN_TYPE));
        }
        final Type responseType = getParameterUpperBound(0, (ParameterizedType) returnType);
        final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
                ? null
                : retrofit.callbackExecutor();
        return new CallAdapter<Object, Call<?>>() {
            @Override
            public Type responseType() {
                return responseType;
            }

            @Override
            public Call<Object> adapt(retrofit2.Call<Object> call) {
                if (executor != null) {
                    return new RealCall<>(executor, call);
                }
                return new RealCall<>(OPTIONAL_NULL_EXECUTOR, call);
            }
        };
    }
}
上一篇 下一篇

猜你喜欢

热点阅读