最近封装了几个View,都和生命周期有关,比如BannerView、和我们公司的ARView,那他们的生命周期怎么绑定呢?刚开始我是直接告诉别人,你自己在哪个activity使用的,就在哪个activity绑定,结果使用的时候被甲方对接人员打回来说这是低级处理方式,wtm这暴脾气,谁tm低级了,但是没办法别人是甲方只能听他的,直接将生命周期的绑定绑在view里面。下面就介绍几个常用的生命周期绑定。
一、使用Application.ActivityLifecycleCallbacks
Application.ActivityLifecycleCallbacks是Android自带的生命周期绑定接口,他有注册与解除方法,当我们进入一个activity的时候就可以注册绑定他了。
//源码
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity var1, Bundle var2);
void onActivityStarted(Activity var1);
void onActivityResumed(Activity var1);
void onActivityPaused(Activity var1);
void onActivityStopped(Activity var1);
void onActivitySaveInstanceState(Activity var1, Bundle var2);
void onActivityDestroyed(Activity var1);
}
简单demo。比如我们要讲一个自定义的View绑定生命周期。
1、先定义一个Application.ActivityLifecycleCallbacks的实现类,为什么这样呢?是因为用户可以要什么选什么,就不用被迫每次都实现全部。
public class ArActivityLifecycle implements Application.ActivityLifecycleCallbacks {
@Override
public void onActivityCreated(Activity activity, Bundle bundle) {
}
@Override
public void onActivityStarted(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}
2、定义一个测试用的view,在构造方法绑定注册生命周期,
public class LifeTestLayout extends RelativeLayout{
private Context context;
public LifeTestLayout(Context context) {
this(context,null);
}
public LifeTestLayout(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public LifeTestLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context=context;
//注册
((Activity)context).getApplication().registerActivityLifecycleCallbacks(lifecycleCallbacks);
}
Application.ActivityLifecycleCallbacks lifecycleCallbacks = new ArActivityLifecycle() {
@Override
public void onActivityPaused(Activity activity) {
super.onActivityPaused(activity);
//判断是当前activity才执行
if (activity == ((Activity)context)) {
Log.d("test", "lifecycleCallbacks-----onActivityPaused--------");
}
}
@Override
public void onActivityResumed(Activity activity) {
super.onActivityResumed(activity);
if (activity == ((Activity)context)) {
Log.d("test", "lifecycleCallbacks-----onActivityResumed--------");
}
}
@Override
public void onActivityDestroyed(Activity activity) {
super.onActivityDestroyed(activity);
if (activity == ((Activity)context)) {
Log.d("test", "lifecycleCallbacks-----onActivityDestroyed--------");
}
}
};
}
((Activity)context).getApplication().registerActivityLifecycleCallbacks(lifecycleCallbacks);这句话是注册生命周期当然他也对应了一个((Activity)context).getApplication().unregisterActivityLifecycleCallbacks(lifecycleCallbacks);解绑方法。
在ActivityLifecycleCallbacks 的实现中判断了返回的activity是否为这个view所在的acrivity因为很多activity都会走这个方法,如果不做判断,其他activity的生命周期也会影响这个view,所以加判断是个好习惯。
二、模仿glide使用fragment绑定生命周期
这次我们模拟一个普通类绑定生命周期这个类名叫Test,哈哈,是不是很高大上?但是写Test类之前先定义我们要绑定的生命周期接口LifecycleListener
public interface LifecycleListener {
/**
* Callback for when {@link android.app.Fragment#onStart()}} or {@link android.app.Activity#onStart()} is called.
*/
void onResume();
/**
* Callback for when {@link android.app.Fragment#onStop()}} or {@link android.app.Activity#onStop()}} is called.
*/
void onPause();
/**
* Callback for when {@link android.app.Fragment#onDestroy()}} or {@link android.app.Activity#onDestroy()} is
* called.
*/
void onDestroy();
}
这里我们监听下常用的onResume、onPause、onDestroy。
然后是Test类
public class Test implements LifecycleListener{
@Override
public void onResume() {
Log.d("easyar","onResume----Test--------");
}
@Override
public void onPause() {
Log.d("easyar","onPause----Test--------");
}
@Override
public void onDestroy() {
Log.d("easyar","onDestroy----Test--------");
}
}
然后写LifecycleDetector,尝试将test类的实例与fragment绑定
public class LifecycleDetector {
static final String FRAGMENT_TAG = "com.bumptech.glide.manager";
private static volatile LifecycleDetector sInstance;
public static LifecycleDetector getInstance() {
if (sInstance == null) {
synchronized (LifecycleDetector.class) {
if (sInstance == null) {
sInstance = new LifecycleDetector();
}
}
}
return sInstance;
}
public void observer(FragmentActivity activity, LifecycleListener lifecycleListener) {
// 获取当前activity的FragmentManager
FragmentManager fm = activity.getSupportFragmentManager();
// 注册无UI的fragment
LifecycleManagerFragment current = getRequestManagerFragment(fm);
current.getLifecycle().addListener(lifecycleListener);
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
LifecycleManagerFragment getRequestManagerFragment(final FragmentManager fm) {
LifecycleManagerFragment current = (LifecycleManagerFragment) fm.findFragmentByTag(FRAGMENT_TAG);
if (current == null) {
current = new LifecycleManagerFragment();
fm.beginTransaction().add(current, FRAGMENT_TAG).commitAllowingStateLoss();
}
return current;
}
}
定义没有布局的fragment实例
public class LifecycleManagerFragment extends Fragment {
private final ActivityFragmentLifecycle lifecycle;
public LifecycleManagerFragment() {
this(new ActivityFragmentLifecycle());
}
// For testing only.
@SuppressLint("ValidFragment")
LifecycleManagerFragment(ActivityFragmentLifecycle lifecycle) {
this.lifecycle = lifecycle;
}
public ActivityFragmentLifecycle getLifecycle() {
return lifecycle;
}
@Override
public void onResume() {
super.onResume();
if(lifecycle!=null){
lifecycle.onResume();
}
}
@Override
public void onPause() {
super.onPause();
if(lifecycle!=null){
lifecycle.onPause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if(lifecycle!=null){
lifecycle.onDestroy();
}
}
}
然后保存fragment和Requestmanager关系
// 实现类,保存fragment和Requestmanager映射关系的类,管理LifecycleListener
public class ActivityFragmentLifecycle implements Lifecycle {
private final Set<LifecycleListener> lifecycleListeners =
Collections.newSetFromMap(new WeakHashMap<LifecycleListener, Boolean>());
@Override
public void addListener(LifecycleListener listener) {
lifecycleListeners.add(listener);
}
void onResume() {
for (LifecycleListener lifecycleListener : OCUtil.getSnapshot(lifecycleListeners)) {
lifecycleListener.onResume();
}
}
void onPause() {
for (LifecycleListener lifecycleListener : OCUtil.getSnapshot(lifecycleListeners)) {
lifecycleListener.onPause();
}
}
void onDestroy() {
for (LifecycleListener lifecycleListener : OCUtil.getSnapshot(lifecycleListeners)) {
lifecycleListener.onDestroy();
}
}
}
还有一个遗漏的接口
public interface Lifecycle {
void addListener(LifecycleListener listener);
}
上面这些完成后,就可以使用了,我们随便搞个activity试试名字就叫LeftDemoActivity非常好听了有没有!
public class LeftDemoActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_left_demo);
Test test=new Test();
LifecycleDetector.getInstance().observer(this, test);
}
@Override
protected void onResume() {
super.onResume();
Log.d("easyar","onResume----Test--------LeftDemoActivity");
}
@Override
protected void onPause() {
super.onPause();
Log.d("easyar","onPause----Test--------LeftDemoActivity");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("easyar","onDestroy----Test--------LeftDemoActivity");
}
}
当你运行起来的时候,就是成功的时候。
有个东西忘啦,getSnapshot是做保存的,直接把源码拿过来的。
public static <T> List<T> getSnapshot(Collection<T> other) {
// toArray creates a new ArrayList internally and this way we can guarantee entries will not
// be null. See #322.
List<T> result = new ArrayList<T>(other.size());
for (T item : other) {
result.add(item);
}
return result;
}
总结
还有其他的方法我没试过,但是这样的生命周期绑定可以解决挺多bug的,玩过哔哩哔哩的应该会遇到他们的一个bug,就是进入一个视频播放页,然后还没加载完成就息屏,他这个时候异步回调回来视频数据了就会在息屏或锁屏界面播出音频来,这是典型的生命周期bug,我遇到过几次了,如果加入这个绑定轻松就能解决问题啦。
网友评论