Android Jetpack之AAC Lifecycle你用对了吗?(一)

2020/6/9 23:26:36

本文主要是介绍Android Jetpack之AAC Lifecycle你用对了吗?(一),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

原文链接

Android Jetpack是2018年谷歌I/O发布的一系列辅助android开发者的实用工具,合称Jetpack,以帮助开发者构建出色的 Android 应用。Android Jetpack 组件覆盖以下 4 个方面:Architecture、Foundation、Behavior 以及 UI。

Lifecycle则是Architecture Compinents官方架构组件之一。Lifecycle的推出让开发者能够在非Fragment和activity中也能感知到fragment和activity生命周期, 开发者也能更专注于处理逻辑的本身,而很多嵌套在Activity/Fragment中的一些胶水代码,也能很好的剥离出来,避免因无法感知到生命周期存在的内存泄露问题。

引入Lifecycle

Android X版本引入

这里我们使用android X引入方式

 api 'androidx.appcompat:appcompat:1.1.0'
复制代码

appcompat默认已经内置lifecycle-common组件,我们无需单独引用了。

如需要指定java8可添加如下引用

 api 'androidx.lifecycle:lifecycle-common-java8:2.1.0'
复制代码

Support版本的引入

注:support版本默认也有引入lifecycle,这里添加一个注解编译即可

implementation "com.android.support:appcompat-v7:28.0.0"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
//java8使用引入
implementation "android.arch.lifecycle:common-java8:1.1.1"
复制代码

生命周期回调

java7中的用法

public interface LifecycleObserverIml extends LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.On_CREATE)
    void onCreate();

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void onStart();

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume();

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    void onPause();

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void onStop();

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void onDestroy();
}
复制代码

java8中的用法

public interface LifecycleObserverIml8 extends DefaultLifecycleObserver {

    @Override
    default void onCreate(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onStart(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onResume(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onPause(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onStop(@NonNull LifecycleOwner owner) {
    }

    @Override
    default void onDestroy(@NonNull LifecycleOwner owner) {
    }
}
复制代码

在Activity/Frament中进行绑定

绑定

getLifecycle().addObserver(lifecycleObserver);
复制代码

解绑

getLifecycle().removeObserver(lifecycleObserver)
复制代码

使用上是不是既简单又实用呢?那么问题就来了,如果我既要在Fragment中使用也要在Activity中使用,能不能像Glide一样,传进来的是什么级别上下文,内部自动绑定对应的上下文级别的生命周期呢?

答案是肯定的!我们来手撸一个绑定的辅助类

public class LifecycleBindHelper {


    private LifecycleOwner lifecycleOwner;
    // 生命周期回调
    private ArrayMap<Object, LifecycleObserver> lifecyleCallbacks = new ArrayMap<>();


    public static LifecycleBindHelper with(Object object) {
        return new LifecycleBindHelper(object);
    }

    public static LifecycleBindHelper with(AppCompatActivity object) {
        return new LifecycleBindHelper(object);
    }

    public static LifecycleBindHelper with(Fragment object) {
        return new LifecycleBindHelper(object);
    }


    private AppLifecycleBindHelper(Object object) {
        if (object != null && object instanceof LifecycleOwner) {
            lifecycleOwner = (LifecycleOwner) object;
        }
    }

    public LifecycleBindHelper addLifecyleCallback(LifecycleObserver lifecycleObserver) {
        if (hasRefrence() && lifecycleObserver != null) {
            lifecyleCallbacks.put(lifecycleObserver, lifecycleObserver);
            lifecycleOwner.getLifecycle().addObserver(lifecycleObserver);
        }
        return this;
    }

    public LifecycleBindHelper removeLifecyleCallback(LifecycleObserver lifecycleObserver) {
        if (hasRefrence() && lifecycleObserver != null) {
            lifecyleCallbacks.remove(lifecycleObserver);
            this.lifecycleOwner.getLifecycle().removeObserver(lifecycleObserver);
        }
        return this;
    }

    private LifecycleObserver[] getLifecycleCallbacks() {
        LifecycleObserver[] callbacks = new LifecycleObserver[lifecyleCallbacks.values().size()];
        lifecyleCallbacks.values().toArray(callbacks);
        return callbacks;
    }


    public boolean hasRefrence() {
        return null != this.lifecycleOwner;
    }

    /**
     * 清除所有的回调(只能清除当前对象添加的回调,其他方式添加的回调监听可以通过手动移除形式)
     */
    public void clearAll() {
        if (!hasRefrence()) {
            return;
        }
        for (LifecycleObserver lifecycleObserver : getLifecycleCallbacks()) {
            removeLifecyleCallback(lifecycleObserver);
        }
        build();
    }

    /**
     * 构建完成,不需要进行使用时调用
     */
    public void build() {
        lifecyleCallbacks.clear();
        this.lifecycleOwner = null;
    }


}
复制代码

如何利用好lifecycle

愈演愈烈的MVP、MVVM开发模式中,我们会将Activity/Fragment中的原有代码逻辑拆散到各个模块中,好处是各自模块负责管理自己的职责,但缺点对生命周期感知几乎是没有,这样就会有导致有很多胶水代码,每个模块逻辑就像是补丁一样和原始页面紧紧关联在一起。

以MVP开发模式为例,我们如何增强生命周期感知能力呢. 利用刚刚封装好的LifecycleBindHelper,我们针对Presenter封装一层BasePresenter。

使用案例1:登录模块

代码如下:

class BasePresenter implements LifecycleObserverIml {
    private LifecycleBindHelper lifecycleBindHelper;

    private static final String TAG = "BasePresenter";

    private FragmentActivity mActivity;
    private Fragment mFragment;

    public BasePresenter(FragmentActivity context) {
        bindLifecycleOwner(context);
    }

    public BasePresenter(Fragment fragment) {
        bindLifecycleOwner(fragment);
    }

    private void bindLifecycleOwner(Object lifecycleOwner) {
        if (lifecycleBindHelper != null && lifecycleBindHelper.hasReference()) {
            lifecycleBindHelper.clearAll();
        }
        if (lifecycleOwner instanceof FragmentActivity) {
            this.mActivity = (FragmentActivity) lifecycleOwner;
        }
        if (lifecycleOwner instanceof Fragment) {
            this.mFragment = (Fragment) lifecycleOwner;
            this.mActivity = this.mFragment.getActivity();
        }
        lifecycleBindHelper = LifecycleBindHelper.with(lifecycleOwner).
                addLifecycleCallback(this);
    }

    public FragmentActivity getActivity() {
        return mActivity;
    }

    @Override
    public void onStart() {
        Log.e(TAG, "onStart: ");
    }

    @Override
    public void onResume() {
        Log.e(TAG, "onResume: ");
    }

    @Override
    public void onPause() {
        Log.e(TAG, "onPause: ");
    }

    @Override
    public void onStop() {
        Log.e(TAG, "onStop: ");
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy: ");
        if (lifecycleBindHelper.hasReference()) {
            lifecycleBindHelper.clearAll();
        }
    }
}
复制代码

这样我们就能很好在Presenter处理生命周期问题了

使用案例2:播放器场景

在没有使用lifecycle时,我们通常是这样使用的

public class MainPlayerActivity extends AppCompatActivity {
    MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initPlayer();
    }

    public void initPlayer() {
        mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setDataSource(Environment.getExternalStorageDirectory() + "/demo.mp4");
            mediaPlayer.prepare();
            mediaPlayer.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    @Override
    protected void onResume() {
        super.onResume();
        mediaPlayer.start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mediaPlayer.pause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
    }
}
复制代码

当Activity中的生命周期变更后,我们也要同步去变更播放器的状态,看到这里,可能会说这没啥问题呀!设想一下,假设我们有2个甚至更多页面是否都得这样处理一遍呢?

我们来看看使用了lifycycle之后怎样处理的

public class MainPlayerNewActivity extends AppCompatActivity {
    PlayerManager playerManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initPlayer();
    }

    public void initPlayer() {
        playerManager = new PlayerManager(this);
        playerManager.setDataSource(
        Environment.getExternalStorageDirectory() + "/demo.mp4");
    }
}
复制代码
public class PlayerManager extends BasePresenter {
    MediaPlayer mediaPlayer;

    public PlayerManager(FragmentActivity context) {
        super(context);
        mediaPlayer = new MediaPlayer();
    }

    public void setDataSource(String path) {

        try {
            mediaPlayer.setDataSource(path);
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        mediaPlayer.start();
    }

    @Override
    public void onPause() {
        super.onPause();
        mediaPlayer.pause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
    }
}
复制代码

可以发现Activity中的代码是不是少了很多,并且PlayerManager就可以在各个页面进行复用了,并且在外部使用时,也不用关心生命周期变更的问题了。

在这里插入图片描述

源码解析

源码分析以Android X为基础

绑定观察者

public class ComponentActivity extends androidx.core.app.ComponentActivity implements
        LifecycleOwner,
        ViewModelStoreOwner,
        SavedStateRegistryOwner,
        OnBackPressedDispatcherOwner {

    static final class NonConfigurationInstances {
        Object custom;
        ViewModelStore viewModelStore;
    }

    private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
    
    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}
复制代码

从上述代码我们可以看到我们在外部调用getLifecycle(),实际上获取的是LifecycleRegistry类对象。

public class LifecycleRegistry extends Lifecycle {
//省略相关代码.....
}
复制代码

LifecycleRegistry实现了Lifecycle接口,提供了增加/删除的观察者接口函数

public abstract class Lifecycle {

    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    @NonNull
    AtomicReference<Object> mInternalScopeRef = new AtomicReference<>();
    
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);
    
    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);
    
    @MainThread
    @NonNull
    public abstract State getCurrentState();
}
复制代码

通知观察者

public class LifecycleRegistry extends Lifecycle {
//省略相关代码.....

 public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }

    private void moveToState(State next) {
        if (mState == next) {
            return;
        }
        mState = next;
        if (mHandlingEvent || mAddingObserverCounter != 0) {
            mNewEventOccurred = true;
            // we will figure out what to do on upper level.
            return;
        }
        mHandlingEvent = true;
        sync();
        mHandlingEvent = false;
    }
     // happens only on the top of stack (never in reentrance),
    // so it doesn't have to take in account parents
    private void sync() {
        LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
        if (lifecycleOwner == null) {
            throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
                    + "garbage collected. It is too late to change lifecycle state.");
        }
        while (!isSynced()) {
            mNewEventOccurred = false;
            // no need to check eldest for nullability, because isSynced does it for us.
            if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
                backwardPass(lifecycleOwner);
            }
            Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
            if (!mNewEventOccurred && newest != null
                    && mState.compareTo(newest.getValue().mState) > 0) {
                forwardPass(lifecycleOwner);
            }
        }
        mNewEventOccurred = false;
    }
    //省略相关代码.....
    
}
复制代码

通过源码我们可以发现,所有的观察者所接受的事件都是由**handleLifecycleEvent(@NonNull Lifecycle.Event event)**函数来驱动,最后分发到forwardPass和backwardPass这两个函数来进行分发和同步的操作。

forwardPass() 遍历观察者集合,当观察者生命周期状态小于当前生命周期状态时 分发事件

private void forwardPass(LifecycleOwner lifecycleOwner) {

    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            pushParentState(observer.mState);
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}
复制代码

backwardPass() 遍历观察者集合,当观察者生命周期状态大于当前生命周期状态时 分发事件

private void backwardPass(LifecycleOwner lifecycleOwner) {
    Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
            mObserverMap.descendingIterator();
    while (descendingIterator.hasNext() && !mNewEventOccurred) {
        Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
        ObserverWithState observer = entry.getValue();
        while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
                && mObserverMap.contains(entry.getKey()))) {
            Event event = downEvent(observer.mState);
            pushParentState(getStateAfter(event));
            observer.dispatchEvent(lifecycleOwner, event);
            popParentState();
        }
    }
}
复制代码

那么问题就来了,在哪发起调用 handleLifecycleEvent() 函数呢?我们查看ComponentActivity源码似乎只对外提供了一个getLifecycle函数

一番查找后在ComponentActivity中的onCreate函数发现这行代码

public class ComponentActivity extends Activity implements
        LifecycleOwner,
        KeyEventDispatcher.Component {
        
    @SuppressLint("RestrictedApi")
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }
} 
复制代码

把ReportFragment添加到了ComponentActivity中

public class ReportFragment extends Fragment {
    private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";

    public static void injectIfNeededIn(Activity activity) {
         fragments for activities
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            // Hopefully, we are the first to make a transaction.
            manager.executePendingTransactions();
        }
    }
}    
复制代码

这时往下看ReportFragment中的代码,顿时就一目了然了

public class ReportFragment extends Fragment {
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }
    
    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onStop() {
        super.onStop();
        dispatch(Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
        // just want to be sure that we won't leak reference to an activity
        mProcessListener = null;
    }

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        if (activity instanceof LifecycleRegistryOwner) {
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }

}
复制代码

总结:LifecycleRegistry作为Lifecycle的实现类,职责是管理我们所添加的观察者,并存放至观察者集合中,ReportFragment作为生命周期代理的存在,当生命周期发生变更时,会通知和同步给LifecycleRegistry,最后由LifecycleRegistry来通知所有的观察者。所以我们在外部通过获取LifecycleRegistry注册就实现LifecycleObserver的观察者,就能轻松的感知到生命周期的变更了。

最后LifecycleObserver、Lifecycle、LifecycleRegistry、ComponentActivity、 ReportFragment之间的关联可以总结为如下图。

在这里插入图片描述

注:关于Jetpack AAC架构组件系列后续还会分析详解,可以关注公众号,早上八点不定时更新。



这篇关于Android Jetpack之AAC Lifecycle你用对了吗?(一)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程