背景
刚成为 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) {
}
});