}
}
}
复制代码
对于未知跟踪实例,我们可以让MyLocationListener
类实现 LifecycleObserver
,然后在 onCreate
方法中实现 Activity 的 Lifecycle 对其进行初始化,然后配合注解。这意味着对生命周期状态的变化做出响应的逻辑会在MyLocationListener
(而不是在 Activity)中进行声明。让各个组件存储自己的逻辑可使 Activity 和 Fragment 逻辑更易于管理。
同时还要注意的是,如果 Lifecycle
现在未处于良好的状态,则应避免调用某些回调。例如,如果回调在 Activity 状态保存后运行 Fragment 事务,就会触发崩溃,因此我们绝不能调用该回调。为简化此使用场景,Lifecycle
类允许其他对象查询当前状态。
对应到 MyLocationListener 的做法如下:
internal class MyLocationListener(
private val context: Context,
private val lifecycle: Lifecycle,
private val callback: (Location) -> Unit
): LifecycleObserver {
private var enabled = false
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun start() {
if (enabled) {
// connect
}
}
fun enable() {
enabled = true
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
// connect if not connected
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stop() {
// disconnect if connected
}
}
复制代码
对于此实现,LocationListener
类可以完全感知生命周期。如果我们需要从另一个 Activity 或 Fragment 使用 LocationListener
,只需对其进行初始化。所有设置和拆解操作都由类本身管理。
如果您尝试管理整个应用进程的生命周期,请参阅 ProcessLifecycleOwner
。
Applicaiton 生命周期 ProcessLifecycleOwner
通常我们判断在应用是不是处于前后台的做法是:注册一个 registerActivityLifecycleCallbacks(callback),然后在 callback 中利用一个全局变量做计数,在onActivityStarted()中计数加1,在onActivityStopped方法中计数减1,从而判断前后台切换。
而使用ProcessLifecycleOwner可以直接获取应用前后台切换状态(记得先引入lifecycle-process依赖)。使用方式和Activity 中类似,只不过要使用 ProcessLifecycleOwner.get()
获取 ProcessLifecycleOwner,代码如下:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//注册App生命周期观察者
ProcessLifecycleOwner.get().getLifecycle().addObserver(new ApplicationLifecycleObserver());
}
/**
- Application生命周期观察,提供整个应用进程的生命周期
- Lifecycle.Event.ON_CREATE只会分发一次,Lifecycle.Event.ON_DESTROY不会被分发。
- 第一个Activity进入时,ProcessLifecycleOwner将分派Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME。
- 而Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP,将在最后一个Activit退出后后延迟分发。如果由于配置更改而销毁并重新创建活动,则此延迟足以保证ProcessLifecycleOwner不会发送任何事件。
- 作用:监听应用程序进入前台或后台
*/
private static class ApplicationLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onAppForeground() {
Log.w(TAG, “ApplicationObserver: app moved to foreground”);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onAppBackground() {
Log.w(TAG, “ApplicationObserver: app moved to background”);
}
}
}
复制代码
实现自定义 LifecycleOwner
支持库 26.1.0 及更高版本中的 Fragment 和 Activity 已实现 LifecycleOwner
接口。如果你有一个自定义类并希望使其成为 LifecycleOwner
,可以使用 LifecycleRegistry
类,但需要将事件转发到该类,代码如下:
class MyActivity : Activity(), LifecycleOwner {
private lateinit var lifecycleRegistry: LifecycleRegistry
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleRegistry = LifecycleRegistry(this)
lifecycleRegistry.markState(Lifecycle.State.CREATED)
}
public override fun onStart() {
super.onStart()
lifecycleRegistry.markState(Lifecycle.State.STARTED)
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}
复制代码
该 MainActivty 是实现了 Activity 类,而不是 AppcompatActivity(FragmentActivity) 类,所以需要这样的处理。我们来看看 FragmentActivity 中的源码,比如 onCreate
方法和 onPause
方法
public class FragmentActivity extends ComponentActivity implements
ActivityCompat.OnRequestPermissionsResultCallback,
ActivityCompat.RequestPermissionsRequestCodeValidator {
/**
- A {@link Lifecycle} that is exactly nested outside of when the FragmentController
- has its state changed, providing the proper nesting of Lifecycle callbacks
-
- TODO(b/127528777) Drive Fragment Lifecycle with LifecycleObserver
*/
final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this);
protected void onCreate(@Nullable Bundle savedInstanceState) {
···
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
···
}
@Override
protected void onPause() {
super.onPause();
···
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
}
//ComponentActivity.java
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
复制代码
明白了基本的操作,我们再看看看源码是如何实现的,注意,本文不会仔细深究源码,而是梳理一个大概的思路,如果想要讲具体深入每个细节,则可以照着我这个思路深入研究。
源码分析
Lifecycle 五种状态对应六个事件(生命周期)
首先我们来看 Lifecycle 这个类,让脑子里面有一个大致的概念
public abstract class Lifecycle {
/**
- Lifecycle coroutines extensions stashes the CoroutineScope into this field.
- @hide used by lifecycle-common-ktx
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@NonNull
AtomicReference 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(); // 获取当前状态,共五种状态
@SuppressWarnings(“WeakerAccess”)
public enum Event { //对应六个生命周期方法,还多个一个 ON_ANY,可以响应任何事件
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
/**
- Lifecycle states. You can consider the states as the nodes in a graph and
- {@link Event}s as the edges between these nodes.
*/
@SuppressWarnings(“WeakerAccess”)
public enum State { //五种状态,对应生命周期的方法/Event 方法
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
复制代码
如果你觉得还不够清楚,只需要要记住五种状态对应六个生命周期方法(六个事件,ON_ANY 可以忽略)。然后我们再来看看官方的图,五个状态对应六个生命周期方法,六个事件,这句话一定要记住。
Event 表示生命周期事件,与 Activity/Fragment 生命周期方法对应。State 是 Lifecycle 这些生命周期对应的状态,为什么不直接用对应的生命周期设置对应的状态呢,而是设置了五个状态呢?原因很简单,因为 Lifecycle 不仅仅只是给自己用这些状态,还有 LiveData,ViewMode 等控件也会用到这些状态的进行逻辑判断,所以 Google 工程师做了更好的封装和管理。
//Lifecycle.class
- {@link Event#ON_CREATE}, {@link Event#ON_START}, {@link Event#ON_RESUME} events in this class
- are dispatched after the {@link LifecycleOwner}'s related method returns.
- {@link Event#ON_PAUSE}, {@link Event#ON_STOP}, {@link Event#ON_DESTROY} events in this class
- are dispatched before the {@link LifecycleOwner}'s related method is called.
复制代码
Event 中的 ON_CREATE,ON_START,ON_RESUME 是在 LifecyclerOwner 对应的方法执行之后分发,ON_PAUSE,ON_STOP,ON_DESTROY 是在 LifecyclerOwner 对应的方法执行之前分发。
我们的 Activity 因为实现了 LifecycleOwner 才能直接调用 getLifecycle()
,从前面的分析我们可以看到是在 ComponentActivity 中实现了该接口
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
// LifecycleRegistry.java
public class LifecycleRegistry extends Lifecycle {
复制代码
getLifecycle().addObserver(MyObserver())
是我们添加观察者的方式,我们来看看addObserver
方法的实现,因为的实现是LifecycleRegistry
//LifecycleRegistry.java
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
//带状态的观察者,这个状态的作用:新的事件触发后 遍历通知所有观察者时,判断是否已经通知这个观察者了
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
//下面代码的逻辑:通过while循环,把新的观察者的状态 连续地 同步到最新状态mState。
//意思就是:虽然可能添加的晚,但把之前的事件一个个分发给你(upEvent方法),即粘性
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();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter–;
}
复制代码
通过statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
分发事件,我们先来看ObserverWithState
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;
}
复制代码
mLifecycleObserver
的值为Lifecycling.lifecycleEventObserver(observer);
,然后查看方法lifecycleEventObserver
@NonNull
static LifecycleEventObserver lifecycleEventObserver(Object object) {
boolean isLifecycleEventObserver = object instanceof LifecycleEventObserver;
boolean isFullLifecycleObserver = object instanceof FullLifecycleObserver;
···
return new ReflectiveGenericLifecycleObserver(object);
}
复制代码
查看最后一行中的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(LifecycleOwner source, Event event) {
mInfo.invokeCallbacks(source, event, mWrapped); //执行状态变化对应的方法
}
}
复制代码
getInfo
的内容如下:
CallbackInfo getInfo(Class klass) {
CallbackInfo existing = mCallbackMap.get(klass);
if (existing != null) {
return existing;
}
existing = createInfo(klass, null);
return existing;
}
复制代码
处理注解
接下来是重要方法createInfo
,在该方法中进行注解的处理,并存储到 mCallbackMap。提供给后面的观察者调用
//createInfo,遍历方法 处理注解,将
private CallbackInfo createInfo(Class klass, @Nullable Method[] declaredMethods) {
Class superclass = klass.getSuperclass();
Map<MethodReference, Lifecycle.Event> handlerToEvent = new HashMap<>();
if (superclass != null) {
CallbackInfo superInfo = getInfo(superclass);
if (superInfo != null) {
handlerToEvent.putAll(superInfo.mHandlerToEvent);
}
}
Class[] interfaces = klass.getInterfaces();
for (Class intrfc : interfaces) {
for (Map.Entry<MethodReference, Lifecycle.Event> entry : getInfo(
intrfc).mHandlerToEvent.entrySet()) {
verifyAndPutHandler(handlerToEvent, entry.getKey(), entry.getValue(), klass);
}
}
Method[] methods = declaredMethods != null ? declaredMethods : getDeclaredMethods(klass);
boolean hasLifecycleMethods = false;
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();
···
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;
}
复制代码
被观察者通知观察者
观察者进行回调的时候调用了ReflectiveGenericLifecycleObserver
的mInfo.invokeCallbacks(source, event, mWrapped);
,最终会调用到MethodReference
的invokeCallback
方法。
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);
}
}
复制代码
学习福利
【Android 详细知识点思维脑图(技能树)】
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。
还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。
这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
由于篇幅有限,这里以图片的形式给大家展示一小部分。
[外链图片转存中…(img-PYnj5c0d-1720107326172)]
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。