Android JetPack Lifecycle源码分析

本文从本人的《一文搞懂Android JetPack组件原理之Lifecycle、LiveData、ViewModel与源码分析技巧》拆分而来,主要采用自底向上源码分析方法探寻Lifecycle的原理,原文内容更加全面,欢迎收藏。

组件介绍

Lifecycle可以方便我们处理Activity和Fragment的生命周期,可以将一些逻辑更加内聚和解耦,比如把资源的释放操作从Activity的回调代码中解耦出来,放到资源管理类中自动进行。该组件是后两个组件的基石,理解它的原理也有助于我们理解LiveData是如何保证不会造成内存泄漏的

下面是一个简单的使用示例,在自定义LifecycleObserver的实现接口上,用注解的方式声明与生命周期相关联的方法。最后通过lifecycleOwner的getLifecycle()接口拿到Lifecycle管理类,并将定义LifecycleObserver的实现接口注册进去。LifecycleOwner通常是一个Activity或Fragment的实例。

MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void connectListener() {
        ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void disconnectListener() {
        ...
    }
}

lifecycleOwner.getLifecycle().addObserver(new MyObserver());

自底向上分析法

该方法是从使用细节出发,提出问题,再进入源码中探究答案,最后汇总出组件关系图,获得上层视角。在这里以自下向上的方法,分析一下LifeCycle的源码。

提出问题

针对上述示例,可以从输入、处理和输出这三个软件过程角度提出问题:1、Activity/Fragment的生命周期如何转化为不同类型的Lifecycle.Event?2、Lifecycle.Event经过哪些处理?3、如何分发到特定的LifecycleObserver实现?

探究答案

Activity/Fragment的生命周期如何转化为不同类型的Lifecycle.Event

先来看看第一个问题怎么在源码中找到答案,不过在这以前,不妨先简单猜测一下,最直接的想法是:直接在生命周期回调方法中创建对应类型的Event。在接下来的分析中,便可以着重于是不是这么实现的,如果更复杂,那么还有哪些是需要被特别考虑到的。

ComponentActiivty相关代码

public class ComponentActivity extends Activity implements LifecycleOwner, Component {

    private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ReportFragment.injectIfNeededIn(this);
    }

    @CallSuper
    protected void onSaveInstanceState(Bundle outState) {
        Lifecycle lifecycle = this.getLifecycle();
        if (lifecycle instanceof LifecycleRegistry) {
            ((LifecycleRegistry)lifecycle).setCurrentState(State.CREATED);
        }

        super.onSaveInstanceState(outState);
    }

    public Lifecycle getLifecycle() {
        return this.mLifecycleRegistry;
    }
}

从ComponentActiivty这个类中,可以看到它实现了LifecycleOwner接口,该类的子类也就有了提供Lifecycle的能力,除了LifecycleOwner的getLifecycle接口的实现,另外比较重要的就是ReportFragment.injectIfNeededIn(this)这条语句,以及它持有了一个Lifecycle的主要实现类LifecycleRegistry的示例。

ReportFragment的主要实现

public class ReportFragment extends Fragment {

    private static final String REPORT_FRAGMENT_TAG = "android.arch.lifecycle"
            + ".LifecycleDispatcher.report_fragment_tag";
    
    public static void injectIfNeededIn(Activity activity) {
        if (Build.VERSION.SDK_INT >= 29) {
            // On API 29+, we can register for the correct Lifecycle callbacks directly
            activity.registerActivityLifecycleCallbacks(
                    new LifecycleCallbacks());
        }
        // Prior to API 29 and to maintain compatibility with older versions of
        // ProcessLifecycleOwner (which may not be updated when lifecycle-runtime is updated and
        // need to support activities that don't extend from FragmentActivity from support lib),
        // use a framework fragment to get the correct timing of Lifecycle events
        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();
        }
    }
    //...
   
    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }
    
    private void dispatch(@NonNull Lifecycle.Event event) {
        if (Build.VERSION.SDK_INT < 29) {
            // Only dispatch events from ReportFragment on API levels prior
            // to API 29. On API 29+, this is handled by the ActivityLifecycleCallbacks
            // added in ReportFragment.injectIfNeededIn
            dispatch(getActivity(), event);
        }
    }
    
     static void dispatch(@NonNull Activity activity, @NonNull Lifecycle.Event event) {
        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);
            }
        }
    }
   //...
}

静态方法injectIfNeededIn的主要作用就是为Activity提供Lifecycle能力,这里分成了两种情况,在Android 10及以上,Activity的源码修改成自己可以注册进LifecycleCallbacks监听器。而为了兼容旧版本,则需要Fragment的生命周期回调中进行分发,这也就是与最初推测相比特殊的地方,可以更加留意。不过这两种情况都是根据生命周期创建了Event枚举型,并最终都经过静态方法dispatch,调用了Lifecyce的handleLifecycleEvent方法。

Lifecycle.Event经过哪些处理

LifecycRegistry

public class LifecycleRegistry extends Lifecycle {
   /**
    * Custom list that keeps observers and can handle removals / additions during traversal.
    *
    * Invariant: at any moment of time for observer1 & observer2:
    * if addition_order(observer1) < addition_order(observer2), then
    * state(observer1) >= state(observer2),
    */
    private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
    private State mState;
    private final WeakReference<LifecycleOwner> mLifecycleOwner;
    
    public LifecycleRegistry(@NonNull LifecycleOwner provider) {
        mLifecycleOwner = new WeakReference<>(provider);
        mState = INITIALIZED;
    }
   
    public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
        State next = getStateAfter(event);
        moveToState(next);
    }

    private void moveToState(State next) {
        if (mState == next) {
            return;
        }
        mState = next;
        ......
        sync();
        ......
    }
    ...
}

跟着源码可以定位到Lifecycle的实现类LifecycRegistry中,它主要是封装了对Lifecycle.Event的操作,包括了Lifecycle.Event与Lifecycle.State的同步,以及Lifecycle.State变化后通知观察者。

先来看handleLifecycleEnvent的实现,通过传进来的event获取一个state枚举值,具体的实现代码如下:

static State getStateAfter(Event event) {
    switch(event) {
        case ON_CREATE:
        case ON_STOP:
            return State.CREATED;
        case ON_START:
        case ON_PAUSE:
            return State.STARTED;
        case ON_RESUME:
            return State.RESUMED;
        case ON_DESTROY:
            return State.DESTROYED;
        case ON_ANY:
        default:
            throw new IllegalArgumentException("Unexpected event value " + event);
    }
}

官网中有一张图用来解释Event和State的对应关系
Event和State的对应关系

getStateAfter()方法既是获取Event事件之后的状态,可以从图中的箭头方向可知具体的状态值,比如ON_START和ON_PAUSE的箭头都指向了STARTED状态,也就是这俩个事件后Lifecycle处于STARTED状态。

回到handleLifecycleEvent()方法,获取新状态后,就调用了moveToState()方法,该方法主要是判断新状态与当前状态相比是否发生改变,如果已改变,则调用sync()同步方法继续处理。

在进一步跟踪方法调用前,不妨先看看LifecycleRegistry有哪些属性,除了上面提到的mState来表示当前Lifecycle的状态外,还有一个比较特殊和重要的属性是mObserverMap。

/**
 * Custom list that keeps observers and can handle removals / additions during traversal.
 *
 * Invariant: at any moment of time for observer1 & observer2:
 * if addition_order(observer1) < addition_order(observer2), then
 * state(observer1) >= state(observer2),
 */
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();

该属性可看作是一个自定义的Map,是一个可遍历的集合,也就是说其中的元素是有序的,封装了监听者LifecycleObserver和监听者的封装ObserverWithState之间的映射关系,根据注释可以知道,在遍历操作其中的监听者时,会保证其中监听者的状态是从大到小排序的。

监听者的封装ObserverWithState则是维护了每一个监听者和其状态,该状态主要是为了给调用事件分发前的判断,另外,在分发Event事件后会同步更新自己的状态。

static class ObserverWithState {
    State mState;
    LifecycleEventObserver mLifecycleObserver;

    ObserverWithState(LifecycleObserver observer, State initialState) {
        mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
        mState = initialState;
    }

    void dispatchEvent(LifecycleOwner owner, Event event) {
        State newState = getStateAfter(event);
        mState = min(mState, newState);
        mLifecycleObserver.onStateChanged(owner, event);
        mState = newState;
    }
}

接下来继续跟踪方法调用,来看看sync()做了哪些处理。

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;
}

该方法通过比较当前状态和mObserverMap元素的枚举值来确定是否分发事件,由于mObserverMap里元素是按状态的大到小排序的,所以这里只需要拿第一位和最后一位元素的状态与当前状态比较,就可以判断是否需要分发事件,以及是分发降级事件,还是分发升级事件。再具体一点说,如果mObserverMap里最大状态比当前状态大,那就需要调用backwardPass(),遍历mObserverMap,同步其中每一个observer状态的同时,分发降级事件,反之,如果mObserverMap里最小状态比当前状态小,就调用forwardPass()分发升级事件。

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();
        }
    }
} 

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()和forwardPass()类似,分别是以降序和升序的方式遍历mObserverMap中的observer,再以内部循环通过downEvent()和upEvent()获取下一步的Event事件,并通过observer.dispatchEvent()分发事件和同步状态。直到mObserverMap中的每一个observer的状态都与当前状态一致为止。

 private static Event downEvent(State state) {
     switch (state) {
         case INITIALIZED:
             throw new IllegalArgumentException();
         case CREATED:
             return ON_DESTROY;
         case STARTED:
             return ON_STOP;
         case RESUMED:
             return ON_PAUSE;
         case DESTROYED:
             throw new IllegalArgumentException();
     }
     throw new IllegalArgumentException("Unexpected state value " + state);
 }

private static Event upEvent(State state) {
    switch (state) {
        case INITIALIZED:
        case DESTROYED:
            return ON_CREATE;
        case CREATED:
            return ON_START;
        case STARTED:
            return ON_RESUME;
        case RESUMED:
            throw new IllegalArgumentException();
    }
    throw new IllegalArgumentException("Unexpected state value " + state);
}

downEvent()和upEvent()的实现同样可以从官网给的Event与State的关系图中找到对应关系。下面再看一下这张图。
Event和State的对应关系

向后箭头对应的事件,而upEvent()升级事件则是状态向前箭头对应的事件。比如说CREATED的升级事件是ON_START,通过ON_START,CREATED升级为STARTED。CREATED的降级事件是ON_DESTROY,通过ON_DESTROY,CREATED降级为DESTROY。

方法调用流转到这里,已经分析完Event从创建到分发的处理过程,接下来就来解决刚开始提出的第三个问题。

如何分发到特定的LifecycleObserver实现

通过ObserverWithState,可以发现dispatchEvent()方法是直接调用mLifecycleObserver接口的onStateChanged()进行的事件分发,那么mLifecycleObserver的具体实现是怎样的呢?通过 mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer)可以知道静态方法Lifecycling.lifecycleEventObserver()对传入的监听者进行了处理,接下来就来看看该方法是怎么实现的。

static LifecycleEventObserver lifecycleEventObserver(Object object) {
    boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
    boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
    if (isLifecycleEventObserver && isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object,
                                                (LifecycleEventObserver) object);
    }
    if (isFullLifecycleObserver) {
        return new FullLifecycleObserverAdapter((FullLifecycleObserver) object, null);
    }

    if (isLifecycleEventObserver) {
        return (LifecycleEventObserver) object;
    }

    final Class<?> klass = object.getClass();
    int type = getObserverConstructorType(klass);
    if (type == GENERATED_CALLBACK) {
        List<Constructor<? extends GeneratedAdapter>> constructors =
            sClassToAdapters.get(klass);
        if (constructors.size() == 1) {
            GeneratedAdapter generatedAdapter = createGeneratedAdapter(
                constructors.get(0), object);
            return new SingleGeneratedAdapterObserver(generatedAdapter);
        }
        GeneratedAdapter[] adapters = new GeneratedAdapter[constructors.size()];
        for (int i = 0; i < constructors.size(); i++) {
            adapters[i] = createGeneratedAdapter(constructors.get(i), object);
        }
        return new CompositeGeneratedAdaptersObserver(adapters);
    }
    return new ReflectiveGenericLifecycleObserver(object);
}

该方法主要将传入的监听者进行封装,方便生命周期事件的转发,这个封装分成了三种方式,每一种可看作是后面的优化,第一种性能最高,传入的监听者直接是接口的实例,但由于生命周期回调方法比较多,接口的实例默认是实现了所有方法,而大部分情况并不需要监听所有生命周期,所以这一部分在java8接口默认方法的支持下比较好用。第二种是判断传入的监听者是不是已用注解解析器处理,生成了对应的封装类,如果项目中配置了注解解析,那么在编译过程中就会生成相应的类型,相对应于运行时反射解析方法的方式,编译时通过注解生成类型在代码执行时性能更高。第三种就是运行时反射解析的处理了,限于篇幅,这里就只追踪一下第三种方式的处理过程。

直接定位到ReflectiveGenericLifecycleObserver类。

class ReflectiveGenericLifecycleObserver implements LifecycleEventObserver {
    private final Object mWrapped;
    private final CallbackInfo mInfo;

    ReflectiveGenericLifecycleObserver(Object wrapped) {
        mWrapped = wrapped;
        mInfo = ClassesInfoCache.sInstance.getInfo(mWrapped.getClass());
    }

    @Override
    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Event event) {
        mInfo.invokeCallbacks(source, event, mWrapped);
    }
}

该类的实现很简单,在创建实例时,使用getInfo()方法,通过传入监听者的class,构造出CallbackInfo实例。在接受到生命周期回调后,方法流转到CallbackInfo实例的invokeCallbacks()方法上。

CallbackInfo getInfo(Class<?> klass) {
    CallbackInfo existing = mCallbackMap.get(klass);
    if (existing != null) {
        return existing;
    }
    existing = createInfo(klass, null);
    return existing;
}

getInfo()查看是否已有缓存,如果没有,就调用createInfo()方法解析class对象。

private CallbackInfo createInfo(Class<?> klass, @Nullable Method[] declaredMethods) {
    Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
    ...
    Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
    for (Method method : methods) {
        OnLifecycleEvent annotation = method.getAnnotation(OnLifecycleEvent.class);
        if (annotation == null) {
            continue;
        }
        hasLifecycleMethods = true;
        Class<?>[] params = method.getParameterTypes();
        int callType = CALL_TYPE_NO_ARG;
        if (params.length > 0) {
            callType = CALL_TYPE_PROVIDER;
            if (!params[0].isAssignableFrom(LifecycleOwner.class)) {
                throw new IllegalArgumentException(
                    "invalid parameter type. Must be one and instanceof LifecycleOwner");
            }
        }
        Lifecycle.Event event = annotation.value();

        if (params.length > 1) {
            callType = CALL_TYPE_PROVIDER_WITH_EVENT;
            if (!params[1].isAssignableFrom(Lifecycle.Event.class)) {
                throw new IllegalArgumentException(
                    "invalid parameter type. second arg must be an event");
            }
            if (event != Lifecycle.Event.ON_ANY) {
                throw new IllegalArgumentException(
                    "Second arg is supported only for ON_ANY value");
            }
        }
        if (params.length > 2) {
            throw new IllegalArgumentException("cannot have more than 2 params");
        }
        MethodReference methodReference = new MethodReference(callType, method);
        verifyAndPutHandler(handlerToEvent, methodReference, event, klass);
    }
    CallbackInfo info = new CallbackInfo(handlerToEvent);
    mCallbackMap.put(klass, info);
    mHasLifecycleMethods.put(klass, hasLifecycleMethods);
    return info;
}

createInfo()方法主要是对类中的方法的遍历处理,这里只接受三种类型的方法,使用callType区分,第一种CALL_TYPE_NO_ARG是没有参数的方法,第二种CALL_TYPE_PROVIDER是一个参数的方法,参数类型为LifecycleOwner本身,第三种CALL_TYPE_PROVIDER_WITH_EVENT是二个参数的方法,第一个参数类型同CALL_TYPE_PROVIDER一样,第二个参数则是ON_ANY枚举值的Event。

每次遍历会将方法用MethodReference封装起来,并使用hanlderToEvent建立MethodReference与event的映射关系,注意这时候一个方法只能有一种Event事件类型相对应,最后以hanlderToEvent这个map创建CallbackInfo对象。

static class CallbackInfo {
    final Map<Lifecycle.Event, List<MethodReference>> mEventToHandlers;
    final Map<MethodReference, Lifecycle.Event> mHandlerToEvent;

    CallbackInfo(Map<MethodReference, Lifecycle.Event> handlerToEvent) {
        mHandlerToEvent = handlerToEvent;
        mEventToHandlers = new HashMap<>();
        for (Map.Entry<MethodReference, Lifecycle.Event> entry : handlerToEvent.entrySet()) {
            Lifecycle.Event event = entry.getValue();
            List<MethodReference> methodReferences = mEventToHandlers.get(event);
            if (methodReferences == null) {
                methodReferences = new ArrayList<>();
                mEventToHandlers.put(event, methodReferences);
            }
            methodReferences.add(entry.getKey());
        }
    }

    @SuppressWarnings("ConstantConditions")
    void invokeCallbacks(LifecycleOwner source, Lifecycle.Event event, Object target) {
        invokeMethodsForEvent(mEventToHandlers.get(event), source, event, target);
        invokeMethodsForEvent(mEventToHandlers.get(Lifecycle.Event.ON_ANY), source, event,
                              target);
    }

    private static void invokeMethodsForEvent(List<MethodReference> handlers,
                                              LifecycleOwner source, Lifecycle.Event event, Object mWrapped) {
        if (handlers != null) {
            for (int i = handlers.size() - 1; i >= 0; i--) {
                handlers.get(i).invokeCallback(source, event, mWrapped);
            }
        }
    }
}

CallbakcInfo在创建时,会解析hanlderToEvent,把一个MethodReference对应一个event的关系,转化为一个event对应多个MethodReference,并存入到mEventToHandlers中。这样在被调用invokeCallbacks()方法时,只需要从mEventToHandlers中取出对应的MethodReference,就可以回调监听者了。

static final class MethodReference {
    final int mCallType;
    final Method mMethod;

    MethodReference(int callType, Method method) {
        mCallType = callType;
        mMethod = method;
        mMethod.setAccessible(true);
    }

    void invokeCallback(LifecycleOwner source, Lifecycle.Event event, Object target) {
        //noinspection TryWithIdenticalCatches
        try {
            switch (mCallType) {
                case CALL_TYPE_NO_ARG:
                    mMethod.invoke(target);
                    break;
                case CALL_TYPE_PROVIDER:
                    mMethod.invoke(target, source);
                    break;
                case CALL_TYPE_PROVIDER_WITH_EVENT:
                    mMethod.invoke(target, source, event);
                    break;
            }
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Failed to call observer method", e.getCause());
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
    ...
}

invokeCallback()就是根据callType对mMethod进行反射调用,最终执行到Lifecycling.lifecycleEventObserver()传入的监听器的方法实现中。

到此,Lifecycle的基本流程已经分析完了。接下来,可以使用类图对Lifecycle的处理流程做下总结。

类关系图

该图使用simpleUML工具生成
类图

用最初的使用代码来解释一下这个类图。

lifecycleOwner.getLifecycle().addObserver(new MyObserver());

首先,通过LifecycleOwner拿到Lifecycle示例,LifecycleOwner是提供获取Lifecycle实例的接口,一般ComponentActvitiy和Fragment会实现这个接口,这个新旧代码有些差别,使用时需要区分。

然后,Lifecycle实例一般具体类型是LifecycleRegistry,它里面使用State管理当前的生命周期状态,同时每个监听者LifecycleObserver也都有一个State,表示监听者当前的状态,生命周期事件Event发生后,会在LifecycleRegistry内与State发生互相转化,再使用这个转化后最新的State,与所有监听者的State比较,到达完整无误地通知监听者生命周期事件的目的。

最后,监听者注册进Lifecycle时,一般情况下会使用ReflectiveGenericLifecycleObserver封装,ReflectiveGenericLifecycleObserver本身也是LifecycleObserver接口的实现,它还封装了从传入监听者类中解析的CallbackInfo,在被通知生命周期事件时,会使用CallbackInfo反射调用到用户声明的接口方法实现上。

总结

自底向上的方式分析源码主要在于分析前问题的提出,上面应用了软件过程中的输入、处理和输出这三个角度提出问题,算是比较通用的一种方式。问题提出后,便可以以解决问题为目的分析源码,不至于在茫茫源码中迷失了方向。解决完问题,紧接着把源码的主要流程梳理一遍,做出总结,即可以加深对原理的理解。

参考资料

《一文搞懂Android JetPack组件原理之Lifecycle、LiveData、ViewModel与源码分析技巧》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值