Android Lifecyle

本文详细解析了如何通过自定义观察者来感知Android Activity的生命周期变化,包括观察者的定义、注册过程及事件分发机制。

Lifecycle笔记

主要记录一下自己看源码的过程

既然我们要感知Activity的生命周期,首先我们需要一个观察者:

interface IObserer{
    //可以把你需要的生命周期单独拿出来
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate(owner:LifecycleOwner)

    @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
    fun onLifecycleChange(owner:LifecycleOwner,event:Lifecycle.Event)
}

class MyObserver:IObserver{
    fun onCreate(owner:LifecycleOwner){
        //doSomeThing
    }
    fun onLifecycleChange(owner:LifecycleOwner,event:Lifecycle.Event){
        //doSomething
    }
}

观察者有了以后,就要想办法把他和生命周期关联起来

val myObserver = MyObserver()
lifecycle.addObserver(myObserver)

至此,我们已经可以在MyObserver中感知到Activity的生命周期变化

那么为什么这样就可以感知到生命周期变化呢

点开addObserver源码,发现该方法是属于Lifecycle抽象类的,那么就去找他的实现类

发现 SupportActivity中有个

 private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

那么就看LifecycleRegistry 的addObserver

 @Override
    public void addObserver(LifecycleObserver observer) {
        State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
        // ① 
        ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
        //把myObserver和statefulObserver添加到Map里去,这里我理解为ObserverWithState是用来通知myObserver生命周期变化的
        ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
        ......

    }

SupportActivity在onCreate的时候会添加一个ReportFragment汇报生命周期变化(类如其名)

class ReportFragment

//在onActivityCreated、onStart等生命周期方法中,均会调用dispatch
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类中了
            ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
        }
    }
}

handleLifecycleEvent最后会到这里

private void forwardPass() {
    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);
            //这里进行事件分发,所以事件还是靠的ObserverWithState ,而不是myObserver(之前想岔了,总想着是myObserver来分发事件,)
            observer.dispatchEvent(mLifecycleOwner, upEvent(observer.mState));
            popParentState();
        }
    }
}

接下来进入ObserverWithState.dispatchEvent方法看下

 void dispatchEvent(LifecycleOwner owner, Event event) {
     State newState = getStateAfter(event);
     mState = min(mState, newState);
     //进行事件分发 见 ① 具体实现就是靠注解+反射来实现方法调用
     mLifecycleObserver.onStateChanged(owner, event);
     mState = newState;
 }
static class ObserverWithState {
    State mState;
    GenericLifecycleObserver mLifecycleObserver;
    ObserverWithState(LifecycleObserver observer, State initialState) {
        // ② 这里会把myObserver包装成ReflectiveGenericLifecycleObserver,最终分发事件是靠这个类
        mLifecycleObserver = Lifecycling.getCallback(observer);
        mState = initialState;
    }
}

② 
ReflectiveGenericLifecycleObserver(Object wrapped) {
    //这个mWrapped 就是myObserver
    mWrapped = wrapped;
    mInfo = getInfo(mWrapped.getClass());
}

流程总结:(已感知生命周期变化为目的)

1、定义好我们自己的Observer(实现LifecycleObserver)
2、在Activity中通过lifecycle.addObserver(observer:LifecycleObserver)来关联生命周期
3、生命周期方法被调用时,ReportFragment向MyObserver汇报

lifecycle.addObserver里做的一些事情:
1、LifecycleRegistry把MyObserver和ObserverWithState对象添加到mObserverMap里以备后用
2、当生命周期发生变化是,ReportFragment通过SupportActivity的LifecycleRegistry 调用handleLifecycleEvent,最终从mObserverMap中取出ObserverWithState来分发事件
3、步骤1 中在创建ObserverWithState实例时,会在MyObserver外面包一层ReflectiveGenericLifecycleObserver,最终由ReflectiveGenericLifecycleObserver通过注解反射来调用MyObserver中由OnLifecycleEvent注解的方法

<think> 我们正在处理用户关于Gradle构建时无法解析依赖项`androidx.lifecycle:lifecycle-bom:2.6.2`的问题。参考了提供的引用内容,特别是引用[1]和引用[2]中关于依赖管理和版本控制的描述,我们可以尝试以下步骤来解决。 首先,根据引用[1]中的内容,项目使用了TOML文件进行版本管理,并且在模块的build.gradle.kts文件中使用类似`implementation(libs.androidx.lifecycle.runtime.ktx)`的方式声明依赖。因此,我们需要检查版本管理文件(通常是libs.versions.toml)中是否正确声明了lifecycle相关库的版本。 其次,引用[2]中展示了一个TOML文件的示例,其中有一个`[versions]`块用来定义版本号,一个`[libraries]`块用来定义具体的依赖项。因此,我们需要确保在TOML文件中为`lifecycle-bom`设置了正确的版本。 以下是解决步骤: 1. **检查TOML版本文件**: 打开项目根目录下的`gradle/libs.versions.toml`文件(或者类似的路径,具体取决于项目配置),检查是否有`lifecycle`的版本定义。 在`[versions]`部分,应该有一个条目定义`lifecycle`的版本,例如: ```toml [versions] lifecycle = "2.6.2" # 注意:用户需要的是2.6.2版本 ``` 然后在`[libraries]`部分,应该定义`lifecycle-bom`,例如: ```toml [libraries] androidx-lifecycle-bom = { group = "androidx.lifecycle", name = "lifecycle-bom", version.ref = "lifecycle" } ``` 2. **在模块的build.gradle.kts中引入BOM**: 在需要使用BOM的模块(通常是app模块)的build.gradle.kts文件中,使用平台(platform)方式引入BOM,这样BOM将管理所有Lifecycle组件的版本。 在dependencies块中添加: ```kotlin dependencies { // 引入Lifecycle BOM implementation(platform(libs.androidx.lifecycle.bom)) // 注意:这里使用的是上面定义的别名 // 然后引入其他Lifecycle组件,无需指定版本 implementation(libs.androidx.lifecycle.runtime.ktx) // ... 其他依赖 } ``` 注意:在TOML中我们定义的库别名是`androidx-lifecycle-bom`,但在kts中引用时需要使用转换后的名字(通常是将中划线转换为点),即`libs.androidx.lifecycle.bom`。但实际上,TOML文件中的定义会生成对应的扩展属性,规则是将中划线(-)转换为下划线(_)?或者点(.)?这取决于Gradle版本。在Gradle 8及以上,通常使用点(.)来访问,但TOML中的键名中的中划线会被转换为点(.)或者下划线(_)?根据官方文档,TOML中的键名可以包含字母、数字、下划线、点和中划线,但在Groovy或Kotlin DSL中访问时,中划线会被转换为点(.)。因此,定义时使用`androidx-lifecycle-bom`,在kts中应该使用`libs.androidx.lifecycle.bom`(注意这里有三段:androidx、lifecycle、bom)。 但是,在TOML中定义时,键名是`androidx-lifecycle-bom`,那么在kts中应该这样引用:`libs.androidx.lifecycle.bom`?实际上,Gradle的版本目录会自动将`-`转换为`.`,所以`androidx-lifecycle-bom`在kts中就是`libs.androidx.lifecycle.bom`。 3. **同步Gradle**: 修改后,同步Gradle(点击Android Studio的Sync Now,或者在终端运行`./gradlew --refresh-dependencies`)。 4. **如果问题仍然存在**: - 检查网络连接,确保可以访问Google的Maven仓库(因为androidx库通常托管在Google Maven)。 - 检查项目的根build.gradle.kts文件,确保有google()仓库,例如: ```kotlin repositories { google() mavenCentral() } ``` - 检查TOML文件中版本号是否正确,特别是`2.6.2`是否写成了其他版本(如2.6.3等)。如果用户指定要2.6.2,则确保TOML中版本引用正确。 - 尝试清理缓存:`./gradlew cleanBuildCache` 或者 `./gradlew --refresh-dependencies`。 5. **不使用BOM的情况(如果项目没有使用BOM管理)**: 如果用户不想使用BOM,而是直接指定每个依赖的版本,那么可以在依赖声明中直接指定版本号(不推荐,因为容易导致版本不一致)。但根据用户的问题,他明确使用了`androidx.lifecycle:lifecycle-bom:2.6.2`,所以应该是引入了BOM。 6. **检查Gradle版本和插件版本**: 引用[2]中提到了AGP(Android Gradle Plugin)版本和Kotlin版本。确保这些版本与lifecycle-bom 2.6.2兼容。可以查看lifecycle-bom 2.6.2的发布说明,了解兼容的AGP和Kotlin版本。 注意:如果用户项目中没有使用TOML版本目录,那么需要直接在模块的build.gradle.kts中声明依赖: ```kotlin dependencies { // 引入BOM implementation(platform("androidx.lifecycle:lifecycle-bom:2.6.2")) // 然后添加其他lifecycle依赖,不需要版本号 implementation("androidx.lifecycle:lifecycle-runtime-ktx") } ``` 但是根据引用[1]和[2],用户项目使用了TOML,所以建议按照上述步骤1和2操作。 如果按照上述步骤操作后问题仍然存在,请提供更多错误信息(例如完整的构建错误日志)以便进一步诊断。 相关问题: 1. 如何在Gradle中使用TOML文件管理依赖版本? 2. BOM(Bill of Materials)在依赖管理中有什么作用? 3. 如何解决Gradle构建中的依赖冲突问题? 4. 如何清理Gradle缓存以解决依赖解析问题? </think> ### Gradle构建无法解析依赖项`androidx.lifecycle:lifecycle-bom:2.6.2`的解决方案 #### 1. **检查仓库配置** 确保项目的根`build.gradle.kts`或`settings.gradle.kts`中已添加 **Google Maven仓库**: ```kotlin dependencyResolutionManagement { repositories { google() // 必须添加此仓库 mavenCentral() } } ``` 若缺少`google()`,Gradle无法从官方源下载AndroidX依赖[^1]。 --- #### 2. **验证版本声明(关键步骤)** 在`libs.versions.toml`中确认版本定义: ```toml [versions] lifecycle = "2.6.2" # 确保版本号正确 [libraries] androidx-lifecycle-bom = { group = "androidx.lifecycle", name = "lifecycle-bom", version.ref = "lifecycle" # 指向正确版本 } ``` > ⚠️ 常见错误:版本名拼写错误(如`lifecycle`误写为`lifecyle`)或版本号不一致[^2]。 --- #### 3. **模块级依赖声明** 在模块的`build.gradle.kts`中: ```kotlin dependencies { // 正确引入BOM implementation(platform(libs.androidx.lifecycle.bom)) // 使用平台声明 // 其他组件(无需版本号) implementation(libs.androidx.lifecycle.runtime.ktx) } ``` > ✅ BOM会自动管理子依赖版本,**无需**重复指定版本号。 --- #### 4. **执行依赖刷新** 在终端运行强制刷新: ```bash ./gradlew --refresh-dependencies clean assemble ``` 或点击Android Studio的 **Gradle Sync** → **Refresh Dependencies**(🔄图标)。 --- #### 5. **验证网络与镜像** - 检查网络能否访问 `https://dl.google.com/dl/android/maven2/` - 若使用国内镜像,确保镜像包含AndroidX仓库(如阿里云镜像需配置`google()`代理)。 --- #### 6. **检查Gradle配置** 在`gradle.properties`中启用优化: ```properties # 提升依赖解析稳定性 android.useAndroidX=true org.gradle.jvmargs=-Xmx2048m org.gradle.caching=true ``` --- ### 相关问题 1. 如何排查Gradle其他依赖项解析失败的问题? 2. TOML版本管理相比传统依赖声明有哪些优势? 3. 使用BOM时出现版本冲突应如何解决? 4. Android Studio如何清理Gradle缓存以解决顽固依赖问题? [^1]: 依赖解析需依赖正确的仓库声明 [^2]: TOML文件中版本引用必须严格一致
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值