阅读 402

Jetpack-Lifecycle

Lifecycle-生命周期感知组件

LifecycleJetpack中提供的一个用于感知生命周期的组件,在应用中主要用于监听 ActivityFragment的生命周期变化,在合适的时候释放资源,防止内存泄露。使用Lifecycle可以将依赖组件的代码从生命周期方法移入组件本身中。避免了直接在ActivityFragment的生命周期方法中操作组件。比如,我们常用的方式如下:

class MyActivity:AppCompatActivity() {
    override fun onStart() {
        super.onStart()
        LocationUtils.start()
    }

    override fun onStop() {
        super.onStop()
        LocationUtils.stop()
    }
}
复制代码

如果多个页面都用到了这个工具类,就需要写多遍,如果多人开发,并不能保证一定都会调用对应的方法。这样难以维护。

androidx.lifecycle软件包提供了可用于构建生命周期感知组件的类和接口,这些组件可以根据ActivityFragment的当前生命周期状态自动调整其行为。

相关类和接口

Lifecycle

Lifecycle本身是一个抽象类,用于存储有关组件(如 ActivityFragment)的生命周期状态的信息,并允许其他对象观察此状态。它主要通过两个枚举类:Event和State来关联组件的生命周期。

LifecycleOwner

LifecycleOwner是一个接口,用于返回一个Lifecycle对象,表示生命周期拥有者,提供者,属于被观察的对象。

public interface LifecycleOwner {
    @NonNull
    Lifecycle getLifecycle();
}
复制代码

LifecycleObserver

LifecycleObserver是一个标记接口,任何类都可以通过实现该接口来感知组件生命周期的变化,属于观察对象。

public interface LifecycleObserver {
}
复制代码

实现LifecycleObserver的组件可与实现LifecycleOwner的组件无缝协同工作,因为生命周期所有者可以提供生命周期,而观察者可以注册以观察生命周期。

应用

Activity和Fragment

在应用中,我们常用的就是监听ActivityFragment的生命周期。Support Library 26.1.0及更高版本或AndroidX中FragmentActivity已实现了LifecycleOwner接口。我们只需要将我们的工具类实现接口LifecycleObserver来检测或者感知ActivityFragment的生命周期即可。

  • 1.通过向对应的方法添加注解来监控组件的生命周期状态。
  • 2.通过调用LifecycleaddObserver()方法来添加观察者
class LocationUtils(lifecycle: Lifecycle) : LifecycleObserver {

    init {
        //添加观察者
        lifecycle.addObserver(this)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    fun start() {
        TODO()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    fun stop() {
        TODO()
    }
}

//使用,创建对象后,在需要使用的地方直接调用对应的功能即可,不需要再外面关联组件的生命周期。
val location = LocationUtils(lifecycle)
复制代码

如果我们需要从另一个ActivityFragment使用LocationUtils,只需对其进行初始化。所有设置和拆解操作都由类本身管理。 这样还有一个好处就是:如果start()改成在onResume()中调用,不需要更改调用的地方,只需要更改定义的地方。这样维护成本低。

自定义 LifecycleOwner

如果想把我们自定义的类变成为LifecycleOwner,就需要借助LifecycleRegistry将事件转发到该类,如下代码所示:

public class MyActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry lifecycleRegistry;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        lifecycleRegistry = new LifecycleRegistry(this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

    @Override
    public void onStart() {
        super.onStart();
        lifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return lifecycleRegistry;
    }
}
复制代码

使用生命周期感知组件可以很方便地管理生命周期:

  • 在粗粒度和细粒度位置更新之间切换。
  • 停止和开始视频缓冲。
  • 开始和停止网络连接。 暂停和恢复动画。

如果Lifecycle的实现是AppCompatActivityFragment,那么当调用它们的onSaveInstanceState()方法时,Lifecycle的状态会更改为CREATED并且会分派ON_STOP事件。

实现原理

简单来说:就是通过一个无页面的Fragment。通过在对指定Activity注册无页面的Fragment,传递页面Activity生命周期Fragment。然后通过Fragment绑定LifecycleRegistry,当Fragment的生命周期变化时,回调LifecycleRegistryLifecycleObserver对象相应的生命周期回调方法。

我们观察Activity的生命周期,只要是通过下述代码:

 lifecycle.addObserver(this)
复制代码

就以此为入口,看一下它的实现:getLifecycle()方法返回的是ComponentActivity中的mLifecycleRegistry,如果你用的是support包,它定义SupportActivity中,我这里使用的AndroidX

public class ComponentActivity extends androidx.core.app.ComponentActivity implements ...{
	...
	private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
	...
	@NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
    ...
}
复制代码

我们调用的addObserver()方法,实际上调用的就是LifecycleRegistry里面的:

 public class LifecycleRegistry extends Lifecycle {
 	...
	@Override
	public void addObserver(@NonNull LifecycleObserver observer) {
	    State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
	    //将传进来的observer包装成一个ObserverWithState,并放入集合中
	    ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
	    ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        ...
	    boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
	    State targetState = calculateTargetState(observer);
	    mAddingObserverCounter++;
	    while ((statefulObserver.mState.compareTo(targetState) < 0
	            && mObserverMap.contains(observer))) {
	        pushParentState(statefulObserver.mState);
	        //分发事件
	        statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
	        popParentState();
	        targetState = calculateTargetState(observer);
	    }
    ...
	}
	...
}
复制代码

从上面可以看出有一个while循环,条件是比较观察者被观察者State的序数, DESTROYED、INITIALIZED、CREATED、STARTED和RESUMED的序数依次为0,1,2,3,4。状态变化后,在该循环体中,调用了statefulObserver.dispatchEvent()方法,分发事件。该方法的具体实现如下:

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;
	}
}
复制代码

ObserverWithState创建的时候将传入的observer解析并返回接口LifecycleEventObserver实现类的对象,最后调用它的onStateChanged()方法。我们在使用Lifecycle的时候使用的是注解的方式:@onLifecycleEvent,那么注解处理器会将该注解解析并动态生成GeneratedAdapte代码,这个GeneratedAdapter会把对应的Lifecycle.Event封装为方法调用。最终通过GenericLifecycleObserveonStateChanged方法调用生成的GeneratedAdaptercallMechods()方法进行事件分发。

public class LocationUtils_LifecycleAdapter implements GeneratedAdapter {
	final LocationUtils mReceiver;

	LocationUtils_LifecycleAdapter(LocationUtils receiver) {
		this.mReceiver = receiver;
	}

	@Override
	public void callMethods(LifecycleOwner owner, Lifecycle.Event event, boolean onAny,MethodCallsLogger logger) {
		boolean hasLogger = logger != null;
		if (onAny) {
			return;
		}
		if (event == Lifecycle.Event.ON_START) {
		    if (!hasLogger || logger.approveCall("start", 1)) {
		    	mReceiver.start();
		    }
		    return;
		}
		if (event == Lifecycle.Event.ON_STOP) {
			if (!hasLogger || logger.approveCall("stop", 1)) {
			    mReceiver.stop();
			}
			return;
		}
	}
}
复制代码

上面这个就是状态变化时事件分发的基本流程,那么它是如何感知生命周期状态变化的呢?我们调用LifecycleaddObserver()方法,实际调用的是ComponentActivitymLifecycleRegistry对象的方法,而我们关注Activity的生命周期是从onCreate()开始,所以下面看一下ComponentActivityonCreate()方法:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mSavedStateRegistryController.performRestore(savedInstanceState);
    ReportFragment.injectIfNeededIn(this);
    if (mContentLayoutId != 0) {
        setContentView(mContentLayoutId);
    }
}
复制代码

onCreate()方法中调用了ReportFragmentinjectIfNeedIn()方法。这个方法其实就是往Activity中添加了一个Fragment。而Fragment是依附于Activity的,所以Fragment的生命周期会跟随Activity的生命周期。既然ReportFragment能感知Activity的生命周期,那么它是如何改变状态的?

public class ReportFragment extends Fragment {
    ...
    public static void injectIfNeededIn(Activity activity) {
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
            manager.executePendingTransactions();
        }
    }
    ...
    @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);
        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);
            }
        }
    }
    ...
}
复制代码

从上面可以看出,在ReportFragment对应的生命周期方法中会调用dispatch()方法,并传递对应的事件Lifecycle.Event.XXX,而dispatch()方法中则是调用了LifecycleRegistryhandleLifecycleEvent()方法。

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;
    //状态的变化转化为生命周期事件,然后转发给 LifecycleObserver
    sync();
    mHandlingEvent = false;
}
复制代码

一图胜千语,下面用一张图来总结大致的流程:

KotlinAndroid

关注公众号,获取更多资源

关注下面的标签,发现更多相似文章
评论