Activity/Fragment 结束后如何处理异步回调?

背景

刚成为 Android 小白鼠的时候,基本上都是照搬别人的代码,也不在乎框架不框架,能实现就觉得自己很NB了。所以导致的结果就是在 Activity/Fragment 中写了一堆一堆的代码,操作网络、操作数据库、业务逻辑处理,全在 Activity/Fragment 中进行,现在看起来惨不忍睹啊。。。当时用的网络框架是 Google 的 Volley 框架,网络请求和回调处理也都在界面中处理。那个时候也很少发生在 Activity/Fragment 结束时应用会崩溃,所以也没关注异步回调的问题。至于为啥不崩溃,我只想说我也不知道。。。后来的某次我在项目中使用了 Google 推荐的 MVP,然后问题就来了,在网络请求已经发出还未回调成功的时候按了返回键,十有八九应用会崩溃,这TM就尴尬了。。。

原因

为啥会发生这样的崩溃?其实原因也很简单,回调成功之前,你已经按了返回键,这时 Activity/Fragment 已经被干掉了,回调成功后,在主线程中更新界面,但是界面已经不存在了,自然就“已停止运行”了。

解决方法

在回调成功更新数据前判断当前 Activity/Fragment 是否已经被销毁。

Activity:activity.isFinishing() || activity.isDestroyed()
Fragment:getActivity.isFinishing() || getActivity.isDestroyed()

封装 - 基于Lifeful接口的异步回调框架

Lifeful 接口设计
    public interface Lifeful {
        /**
         * Indicates whether this Activity/Fragment is alive.
         *
         * @return If the activity is finished, returns false; else returns true.
         */
        boolean isAlive();
}
接口生成器
    public interface LifefulGenerator<Callback> {

        /**
         * @return the callback.
         */
        Callback getCallback();

        /**
         * @return the weak reference which bind with life cycle.
         */
        WeakReference<Lifeful> getLifefulWeakReference();

        /**
         * Check to see whether the lifeful is null.
         *
         * @return true if lifeful is null
         */
        boolean isLifefulNull();
}
接口生成器的默认实现

    public class DefaultLifefulGenerator<Callback> implements LifefulGenerator<Callback> {
        private WeakReference<Lifeful> weakReference;
        private boolean isLifefulNull;
        private Callback callback;

        DefaultLifefulGenerator(Callback callback, Lifeful lifeful) {
            this.callback = callback;
            weakReference = new WeakReference<>(lifeful);
            isLifefulNull = lifeful == null;
        }

        /**
         * @return callback
         */
        @Override
        public Callback getCallback() {
            return callback;
        }

        /**
         * @return weak reference
         */
        @Override
        public WeakReference<Lifeful> getLifefulWeakReference() {
            return weakReference;
        }

        /**
         * Returns true if the lifeful is null.
         *
         * @return true if str is null, else false
         */
        @Override
        public boolean isLifefulNull() {
            return isLifefulNull;
        }
    }
通过静态方法判断生命周期是否结束

    public class LifefulUtil {

        /**
         * Check to see whether the Activity/Fragment is destroyed.
         *
         * @param lifefulGenerator lifeful
         * @param <T>              T
         * @return true if
         * 1. lifefulGenerator is null
         * 2. callback is null
         * 3. weakReference is null
         * 4. lifeful which bind with weakReference is null and the lifeful which is passed is not null
         * 5. lifeful which bind with weakReference is not null and lifeful which is passed is not alive.
         * <p>
         * else return false
         */
        public static <T> boolean destroy(LifefulGenerator<T> lifefulGenerator) {
            if (lifefulGenerator == null)
                return true;

            if (lifefulGenerator.getCallback() == null)
                return true;

            if (lifefulGenerator.getLifefulWeakReference() == null)
                return true;

            Lifeful lifeful = lifefulGenerator.getLifefulWeakReference().get();

            return lifeful == null && !lifefulGenerator.isLifefulNull() || lifeful != null && !lifeful.isAlive();

        }
    }

用法

我已经将代码发布到 JCenter ,可以直接作为 library 使用。

Android Studio

    compile 'com.smile:lifeful:1.0.0'

对于 MVP 框架来说,可以在 Model 或 Presenter 层进行异步回调的判断。

在需要判断的 Activity/Fragment 中实现 Lifeful 接口和 isAlive() 方法,你也可以在 BaseActivity/BaseFragment 中实现 Lifeful 接口和 isAlive() 方法,所有的 Activity/Fragment 继承即可。

    @Override
    public boolean isAlive() {
        if (activity == null)
            return false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            return !(activity.isDestroyed() || activity.isFinishing());
        }
        return !activity.isFinishing();
    }

定义回调接口

    public interface OnLoadListener<T> {

        /**
         * Return info when request success
         *
         * @param success success detail
         */
        void onSuccess(T success);

        /**
         * Return info when request fail
         *
         * @param error error detail
         */
        void onError(String error);
    }

Lifeful 实现回调接口,在此类中进行 lifeful 的判断


    public class OnLoadLifefulListener<T> implements OnLoadListener<T> {

        private LifefulGenerator<OnLoadListener<T>> lifefulGenerator;

        public OnLoadLifefulListener(OnLoadListener<T> listener, Lifeful lifeful) {
            lifefulGenerator = new DefaultLifefulGenerator<>(listener, lifeful);
        }

        @Override
        public void onSuccess(T success) {
            if (LifefulUtil.destroy(lifefulGenerator))
                return;
            lifefulGenerator.getCallback().onSuccess(success);
        }

        @Override
        public void onError(String error) {
            if (LifefulUtil.destroy(lifefulGenerator))
                return;
            lifefulGenerator.getCallback().onError(error);
        }
    }

将 Lifeful 传递给 Presenter 层,在 Presenter 层做判断。

    loadModel.load(new OnLoadLifefulListener<>(new OnLoadListener<String>() {
            @Override
            public void onSuccess(String success) {

            }

            @Override
            public void onError(String error) {

            }
        }, lifeful));

当然了,如果你不需要判断,可以直接使用OnLoadListener

    loadModel.load(new OnLoadListener<String>() {
             @Override
             public void onSuccess(String success) {

             }

             @Override
             public void onError(String error) {

             }
         });
Demo请移步 LifefulDemo
Smile Wei wechat
请扫码关注我的微信公众号