浅析 - Android Lifecycle Component

本文深入探讨了Android Lifecycle组件的工作原理,包括初始化流程、状态改变与分发机制,以及生命周期状态的解析。从Lifecycle组件的注册到事件的分发,再到状态的同步,逐一解析,帮助读者全面理解Android应用生命周期管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

关于Lifecycle基础相关的使用与概念请移步这里:

  1. https://blog.youkuaiyun.com/guiying712/article/details/81176039#处理-onstop-事件
  2. https://developer.android.com/topic/libraries/architecture/lifecycle?hl=zh-cn

提出几个问题,方便下面一一回答:

  1. Lifecycle的初始化流程怎样的?
  2. Lifecycle的状态如何改变以及如何分发的?
  3. Lifecycle是如何解析生命周期状态的?

简要介绍相关类

Lifecycle 其内部定义了具有Android生命周期的事件与状态。

LifecycleOwner 代表具有Android生命周期的类。 它最主要的实现类就是AppCompatActivity

LifecycleObserver 标记一个类可以接收生命周期事件的回调。

LifecycleRegisterLifecycle的具体实现,可以处理多个观察者,内部用来处理状态,分发事件。

!

Lifecycle的初始化流程怎样的?

一个组件再好用,如果不经过初始化,也是无根之水。 通过对生命周期注册流程的反跟踪,最后可以找到android.arch.lifecycle.ProcessLifecycleOwnerInitializer类,它作为Lifecycle组件初始化的开始。

由于其继承自ContentProvider,那么必须要在AndroidManifest.xml文件中显示注册ProcessLifecycleOwnerInitializer才会被初始化。

在构建Apk的过程中,Android Studio会将多个模块的AndroidManifest.xml合并到一起,所以查看一下build目录中,是否存在被合并的AndroidManifest.xml文件。

app/build/intermediates/merged_manifests/debug/AndroidManifest.xml

可以很明显的看到<provider>标签在AndroidManifest.xml中被注册。


    <application
       .... >
        ....
        <provider
            android:name="android.arch.lifecycle.ProcessLifecycleOwnerInitializer"
            android:authorities="com.example.application.lifecycle-trojan"
            android:exported="false"
            android:multiprocess="true" />
       ....
    </application>

下面跟着一张时序图,来捋清楚Lifecycle的初始化流程。

在这里插入图片描述

虽然涉及到的类很多,但是逻辑很多简单,都是直接初始化。

其中核心的逻辑就是监听ActivityFragment的全局生命周期回调,最后在Activity创建时向其中添加一个ReportFragment,使用其作为生命周期的分发起始点。而当ActivityFragment生命周期状态发生改变时,都通过LifecycleRegistryOwner来处理生命周期状态的改变。

// 注册Activity的生命周期回调
((Application) context.getApplicationContext()).registerActivityLifecycleCallbacks(new DispatcherActivityCallback());

// 注册Fragment的生命周期回调
((FragmentActivity) activity).getSupportFragmentManager() .registerFragmentLifecycleCallbacks(mFragmentCallback, true);

// injectIfNeededIn,添加ReportFragment到宿主Activity中。
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();

Lifecycle的状态如何改变以及如何分发的?

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

上文曾说过,ReportFragment是分发的核心类,当其生命周期变化时会分发对应的事件,最后走到LifecycleRegister.handleLifecycleEvent(Lifecycle.Event)中。

handleLifecycleEvent()内部做了两件事:

  1. 获取事件对应的下一个状态
  2. 改变当前状态到下一个状态,并同步分发事件

虽然getStateAfter()很短,但是还是看图更易理解:

假设ReportFragment分发了Lifecycle.Event.ON_RESUME,那么根据这个方法,可以得到对应的状态为RESUMED

在这里插入图片描述

最后关键的步骤就是将各个观察者的生命周期状态依次移动到正确的状态,sync()将该过程分为两个步骤,具体如下:

private void sync() {
     LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
     ...
     while (!isSynced()) {
         mNewEventOccurred = false;
         
         // 若最老的观察者状态大于当前状态,那么需要将最老的观察者状态向后移动
         if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
             backwardPass(lifecycleOwner);
         }
         // 若最新的观察者状态小于当前状态,那么需要将最新的观察者状态向前移动
         Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
         if (... mState.compareTo(newest.getValue().mState) > 0) {
             forwardPass(lifecycleOwner);
         }
     }
     mNewEventOccurred = false;
 }

这里以将状态向前移动为例(CREATED => RESUME)来分析下fowardPass()方法:

private void forwardPass(LifecycleOwner lifecycleOwner) {
	// 升序排序
    Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
            mObserverMap.iteratorWithAdditions();
            
    while (ascendingIterator.hasNext() && !mNewEventOccurred) {
        
        ...
        
        // 若目标观察者的状态小于当前状态,那么当前状态对应的事件,并进行分发。
        while ((observer.mState.compareTo(mState) < 0 && ... ) {
			...
            observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
            ...
        }
    }
}

最后已一个时序图结尾:

在这里插入图片描述

Lifecycle是如何解析生命周期状态的?

因为观察者内部是使用注解来标记生命周期方法的,也就不可避免的需要使用的反射。为了反射开销比较大,所以使用了ClassInfoCache作为缓存。 整个流程比较简单,就不详细介绍了。

class MyObserver : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun create() {
        Log.d(TAG, "create() called ")
    }
}

在这里插入图片描述

releaseRuntimeClasspath - Resolved configuration for runtime for variant: release +--- androidx.appcompat:appcompat:1.6.1 | +--- androidx.activity:activity:1.6.0 -> 1.8.0 | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.collection:collection:1.0.0 -> 1.1.0 | | | \--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.core:core:1.8.0 -> 1.9.0 | | | +--- androidx.annotation:annotation:1.2.0 -> 1.3.0 | | | +--- androidx.annotation:annotation-experimental:1.3.0 | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 1.8.22 | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 | | | | \--- org.jetbrains:annotations:13.0 | | | +--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | | | +--- androidx.concurrent:concurrent-futures:1.0.0 -> 1.1.0 | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | \--- com.google.guava:listenablefuture:1.0 | | | +--- androidx.lifecycle:lifecycle-runtime:2.3.1 -> 2.6.1 | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | +--- androidx.arch.core:core-common:2.2.0 | | | | | \--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | +--- androidx.arch.core:core-runtime:2.2.0 | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | | \--- androidx.arch.core:core-common:2.2.0 (*) | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4 | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4 | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4 | | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 (c) | | | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4 (c) | | | | | | | | \--- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.6.4 (c) | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21 -> 1.8.22 | | | | | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 (*) | | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 | | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 (*) | | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-common:1.6.21 -> 1.8.22 | | | | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4 (*) | | | | | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21 -> 1.8.22 (*) | | | | | +--- androidx.lifecycle:lifecycle-livedata:2.6.1 (c) | | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 (c) | | | | | +--- androidx.lifecycle:lifecycle-process:2.6.1 (c) | | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (c) | | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 (c) | | | | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 (c) | | | | +--- androidx.profileinstaller:profileinstaller:1.3.0 | | | | | +--- androidx.annotation:annotation:1.2.0 -> 1.3.0 | | | | | +--- androidx.concurrent:concurrent-futures:1.1.0 (*) | | | | | +--- androidx.startup:startup-runtime:1.1.1 | | | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | | | \--- androidx.tracing:tracing:1.0.0 | | | | | | \--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | | \--- com.google.guava:listenablefuture:1.0 | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-process:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 (c) | | | | \--- androidx.lifecycle:lifecycle-livedata:2.6.1 (c) | | | +--- androidx.versionedparcelable:versionedparcelable:1.1.1 | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | | | \--- androidx.core:core-ktx:1.9.0 (c) | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (*) | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-process:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 (c) | | | \--- androidx.lifecycle:lifecycle-livedata:2.6.1 (c) | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 | | | +--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | | | +--- androidx.core:core-ktx:1.2.0 -> 1.9.0 | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | +--- androidx.core:core:1.9.0 (*) | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 1.8.22 (*) | | | | \--- androidx.core:core:1.9.0 (c) | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 | | | | +--- androidx.arch.core:core-common:2.1.0 -> 2.2.0 (*) | | | | +--- androidx.arch.core:core-runtime:2.1.0 -> 2.2.0 (*) | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (*) | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-livedata:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-process:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 (c) | | | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 (*) | | | +--- androidx.savedstate:savedstate:1.2.1 | | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | | +--- androidx.arch.core:core-common:2.1.0 -> 2.2.0 (*) | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (*) | | | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | +--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4 (*) | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-process:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 (c) | | | \--- androidx.lifecycle:lifecycle-livedata:2.6.1 (c) | | +--- androidx.profileinstaller:profileinstaller:1.3.0 (*) | | +--- androidx.savedstate:savedstate:1.2.1 (*) | | +--- androidx.tracing:tracing:1.0.0 (*) | | \--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 (*) | +--- androidx.annotation:annotation:1.3.0 | +--- androidx.appcompat:appcompat-resources:1.6.1 | | +--- androidx.annotation:annotation:1.2.0 -> 1.3.0 | | +--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | | +--- androidx.core:core:1.6.0 -> 1.9.0 (*) | | +--- androidx.vectordrawable:vectordrawable:1.1.0 | | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | | +--- androidx.core:core:1.1.0 -> 1.9.0 (*) | | | \--- androidx.collection:collection:1.1.0 (*) | | +--- androidx.vectordrawable:vectordrawable-animated:1.1.0 | | | +--- androidx.vectordrawable:vectordrawable:1.1.0 (*) | | | +--- androidx.interpolator:interpolator:1.0.0 | | | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | | | \--- androidx.collection:collection:1.1.0 (*) | | \--- androidx.appcompat:appcompat:1.6.1 (c) | +--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | +--- androidx.core:core:1.9.0 (*) | +--- androidx.core:core-ktx:1.8.0 -> 1.9.0 (*) | +--- androidx.cursoradapter:cursoradapter:1.0.0 | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | +--- androidx.drawerlayout:drawerlayout:1.0.0 -> 1.1.1 | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.core:core:1.2.0 -> 1.9.0 (*) | | \--- androidx.customview:customview:1.1.0 | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.core:core:1.3.0 -> 1.9.0 (*) | | \--- androidx.collection:collection:1.1.0 (*) | +--- androidx.emoji2:emoji2:1.2.0 | | +--- androidx.annotation:annotation:1.2.0 -> 1.3.0 | | +--- androidx.collection:collection:1.1.0 (*) | | +--- androidx.core:core:1.3.0 -> 1.9.0 (*) | | +--- androidx.lifecycle:lifecycle-process:2.4.1 -> 2.6.1 | | | +--- androidx.annotation:annotation:1.2.0 -> 1.3.0 | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (*) | | | +--- androidx.startup:startup-runtime:1.1.1 (*) | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-livedata:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (c) | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 (c) | | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 (c) | | \--- androidx.startup:startup-runtime:1.0.0 -> 1.1.1 (*) | +--- androidx.emoji2:emoji2-views-helper:1.2.0 | | +--- androidx.collection:collection:1.1.0 (*) | | +--- androidx.core:core:1.3.0 -> 1.9.0 (*) | | \--- androidx.emoji2:emoji2:1.2.0 (*) | +--- androidx.fragment:fragment:1.3.6 | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.core:core:1.2.0 -> 1.9.0 (*) | | +--- androidx.collection:collection:1.1.0 (*) | | +--- androidx.viewpager:viewpager:1.0.0 | | | +--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | | | +--- androidx.core:core:1.0.0 -> 1.9.0 (*) | | | \--- androidx.customview:customview:1.0.0 -> 1.1.0 (*) | | +--- androidx.loader:loader:1.0.0 | | | +--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | | | +--- androidx.core:core:1.0.0 -> 1.9.0 (*) | | | +--- androidx.lifecycle:lifecycle-livedata:2.0.0 -> 2.6.1 | | | | +--- androidx.arch.core:core-common:2.1.0 -> 2.2.0 (*) | | | | +--- androidx.arch.core:core-runtime:2.1.0 -> 2.2.0 (*) | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 (*) | | | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.10 -> 1.8.22 (*) | | | | +--- androidx.lifecycle:lifecycle-common:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-livedata-core:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-process:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-runtime:2.6.1 (c) | | | | +--- androidx.lifecycle:lifecycle-viewmodel:2.6.1 (c) | | | | \--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.1 (c) | | | \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 -> 2.6.1 (*) | | +--- androidx.activity:activity:1.2.4 -> 1.8.0 (*) | | +--- androidx.lifecycle:lifecycle-livedata-core:2.3.1 -> 2.6.1 (*) | | +--- androidx.lifecycle:lifecycle-viewmodel:2.3.1 -> 2.6.1 (*) | | +--- androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1 -> 2.6.1 (*) | | +--- androidx.savedstate:savedstate:1.1.0 -> 1.2.1 (*) | | \--- androidx.annotation:annotation-experimental:1.0.0 -> 1.3.0 (*) | +--- androidx.lifecycle:lifecycle-runtime:2.5.1 -> 2.6.1 (*) | +--- androidx.lifecycle:lifecycle-viewmodel:2.5.1 -> 2.6.1 (*) | +--- androidx.resourceinspection:resourceinspection-annotation:1.0.1 | | \--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | +--- androidx.savedstate:savedstate:1.2.0 -> 1.2.1 (*) | +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.10 -> 1.8.22 (*) | \--- androidx.appcompat:appcompat-resources:1.6.1 (c) +--- com.google.android.material:material:1.10.0 -> 1.11.0 | +--- org.jetbrains.kotlin:kotlin-bom:1.8.22 | | +--- org.jetbrains.kotlin:kotlin-stdlib:1.8.22 (c) | | +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.8.22 (c) | | +--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22 (c) | | \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22 (c) | +--- com.google.errorprone:error_prone_annotations:2.15.0 | +--- androidx.activity:activity:1.8.0 (*) | +--- androidx.annotation:annotation:1.2.0 -> 1.3.0 | +--- androidx.appcompat:appcompat:1.6.1 (*) | +--- androidx.cardview:cardview:1.0.0 | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | +--- androidx.coordinatorlayout:coordinatorlayout:1.1.0 | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.core:core:1.1.0 -> 1.9.0 (*) | | +--- androidx.customview:customview:1.0.0 -> 1.1.0 (*) | | \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | +--- androidx.constraintlayout:constraintlayout:2.0.1 -> 2.1.4 | | +--- androidx.appcompat:appcompat:1.2.0 -> 1.6.1 (*) | | +--- androidx.core:core:1.3.2 -> 1.9.0 (*) | | \--- androidx.constraintlayout:constraintlayout-core:1.0.4 | +--- androidx.core:core:1.6.0 -> 1.9.0 (*) | +--- androidx.drawerlayout:drawerlayout:1.1.1 (*) | +--- androidx.dynamicanimation:dynamicanimation:1.0.0 | | +--- androidx.core:core:1.0.0 -> 1.9.0 (*) | | +--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | | \--- androidx.legacy:legacy-support-core-utils:1.0.0 | | +--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | | +--- androidx.core:core:1.0.0 -> 1.9.0 (*) | | +--- androidx.documentfile:documentfile:1.0.0 | | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | | +--- androidx.loader:loader:1.0.0 (*) | | +--- androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 | | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | | \--- androidx.print:print:1.0.0 | | \--- androidx.annotation:annotation:1.0.0 -> 1.3.0 | +--- androidx.annotation:annotation-experimental:1.0.0 -> 1.3.0 (*) | +--- androidx.fragment:fragment:1.2.5 -> 1.3.6 (*) | +--- androidx.lifecycle:lifecycle-runtime:2.0.0 -> 2.6.1 (*) | +--- androidx.recyclerview:recyclerview:1.0.0 -> 1.1.0 | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.core:core:1.1.0 -> 1.9.0 (*) | | +--- androidx.customview:customview:1.0.0 -> 1.1.0 (*) | | \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | +--- androidx.resourceinspection:resourceinspection-annotation:1.0.1 (*) | +--- androidx.transition:transition:1.2.0 | | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | | +--- androidx.core:core:1.0.1 -> 1.9.0 (*) | | \--- androidx.collection:collection:1.0.0 -> 1.1.0 (*) | +--- androidx.vectordrawable:vectordrawable:1.1.0 (*) | \--- androidx.viewpager2:viewpager2:1.0.0 | +--- androidx.annotation:annotation:1.1.0 -> 1.3.0 | +--- androidx.fragment:fragment:1.1.0 -> 1.3.6 (*) | +--- androidx.recyclerview:recyclerview:1.1.0 (*) | +--- androidx.core:core:1.1.0 -> 1.9.0 (*) | \--- androidx.collection:collection:1.1.0 (*) +--- com.google.android.material:material:1.11.0 (*) +--- androidx.activity:activity:1.8.0 (*) \--- androidx.constraintlayout:constraintlayout:2.1.4 (*) (c) - A dependency constraint, not a dependency. The dependency affected by the constraint occurs elsewhere in the tree. (*) - Indicates repeated occurrences of a transitive dependency subtree. Gradle expands transitive dependency subtrees only once per project; repeat occurrences only display the root of the subtree, followed by this annotation. A web-based, searchable dependency report is available by adding the --scan option. BUILD SUCCESSFUL in 20s 1 actionable task: 1 executed
最新发布
06-13
<think>我们已经知道用户遇到的是MaterialComponents资源找不到的问题,并且之前已经给出了解决方案。但根据用户新的提示,他们可能遇到了更复杂的依赖冲突,特别是涉及androidx.appcompat:appcompat和Material库的冲突。用户当前的错误是:`resourcestyle/Widget.MaterialComponents.ActionBarnotfound`,而他们使用的appcompat版本是1.6.1。同时,用户提到了使用`releaseRuntimeClasspath`进行依赖分析。因此,我们需要重点解决:1.确保Material库被正确引入且版本兼容。2.解决可能存在的appcompat和Material库的版本冲突(因为Material库依赖于appcompat,但版本必须一致)。3.检查主题设置是否正确。步骤:1.首先,确认Material库依赖的版本与appcompat版本兼容。Material库的版本应该与appcompat版本匹配(例如,二者应使用相同的版本号基础,或者至少是兼容的版本)。查看Material库的发布说明:通常,Material库的版本号与appcompat的版本号是同步的,例如Material库1.6.1对应appcompat1.6.1。2.如果用户已经引入了appcompat:1.6.1,那么Material库也应该使用1.6.1(或相近的补丁版本,如1.6.0也可以,但最好一致)。3.在build.gradle中,添加:implementation'com.google.android.material:material:1.6.1'//与appcompat版本一致4.检查是否混用了support库(v4/v7)和androidx库。在引用中[3]提到,有项目因为使用了v4库而出现问题,改为v7后解决,但现在我们使用androidx,所以不应该出现support库。确保所有依赖都迁移到了androidx。5.执行依赖检查,查看是否有多个版本的appcompat或Material库:./gradlew:app:dependencies--configurationreleaseRuntimeClasspath6.如果发现冲突,可以使用以下方式强制统一版本(在build.gradle中):configurations.all{resolutionStrategy{force'androidx.appcompat:appcompat:1.6.1'force'com.google.android.material:material:1.6.1'}}7.清理项目,重新构建。8.确认主题设置:在styles.xml中,主题的parent应该是MaterialComponents主题,例如:<stylename="AppTheme"parent="Theme.MaterialComponents.Light.DarkActionBar">...</style>9.在AndroidManifest.xml中,确保application或activity使用了这个主题。另外,注意引用[4]中提到,缺少appcompat依赖会导致类似问题,所以必须确保appcompat被正确引入。因此,我们分步骤说明:步骤1:添加正确的Material库依赖步骤2:统一依赖版本(解决冲突)步骤3:检查并修正主题步骤4:清理和重建下面开始编写回答:</think> ### 解决AAPT错误:`style/Widget.MaterialComponents.ActionBar not found`的进阶方案 结合引用[3][4]中的依赖冲突案例,以下是更全面的解决方案: #### 🔧 **核心解决步骤** 1. **统一Material与AppCompat版本** ```gradle // build.gradle (app模块) dependencies { def material_version = "1.11.0" // 与appcompat版本保持一致 implementation "com.google.android.material:material:$material_version" implementation "androidx.appcompat:appcompat:$material_version" // 强制统一所有传递依赖的版本 (引用[3]) configurations.all { resolutionStrategy { force "androidx.appcompat:appcompat:1.11.0" force "com.google.android.material:material:1.11.0" } } } ``` 2. **检查依赖冲突** 运行命令分析依赖树: ```bash ./gradlew :app:dependencies --configuration releaseRuntimeClasspath > deps.txt ``` 检查输出中是否存在: - 多个不同版本的Material库(如1.11.0和1.6.1共存) - 混用androidx和support库(如`com.android.support:appcompat-v7`) 3. **修正混用问题**(引用[4]) ```gradle // 替换所有support库为androidx等效库 implementation 'androidx.appcompat:appcompat:1.11.0' // 替代com.android.support:appcompat-v7 implementation 'androidx.legacy:legacy-support-v4:1.0.0' // 替代com.android.support:support-v4 ``` 4. **验证主题配置** ```xml <!-- res/values/themes.xml --> <style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight.DarkActionBar"> <item name="actionBarStyle">@style/Widget.MaterialComponents.ActionBar</item> <!-- 保持与父主题一致 --> </style> ``` 5. **清理缓存**(关键步骤) ```bash # 终端执行 ./gradlew clean rm -rf ~/.gradle/caches ``` #### ⚠️ **依赖冲突解决技巧** 当出现版本冲突时: 1. 使用`resolutionStrategy`强制统一版本: ```gradle configurations.all { resolutionStrategy.eachDependency { details -> if (details.requested.group == 'com.google.android.material') { details.useVersion "1.11.0" } if (details.requested.group == 'androidx.appcompat') { details.useVersion "1.11.0" } } } ``` 2. 检测冲突模块: ```gradle // build.gradle顶部添加 task checkConflict { doLast { configurations.compileClasspath.resolvedConfiguration .firstLevelModuleDependencies.each { dep -> dep.children.each { child -> if (dep.moduleName != child.moduleName) { println "${dep.moduleGroup}:${dep.moduleName} -> ${child.moduleGroup}:${child.moduleName}" } } } } } ``` 运行`./gradlew checkConflict`查看冲突链条[^3] #### 🧩 **问题根本原因** ```mermaid graph TD A[资源未找到错误] --> B{依赖冲突分析} B --> C[多个Material版本共存] B --> D[混用Support/AndroidX] B --> E[传递依赖冲突] C --> F1(强制统一版本) D --> F2(迁移到AndroidX) E --> F3(使用resolutionStrategy) ``` #### 🔍 关键验证点 1. 在`build/outputs/logs/manifest-merger-debug-report.txt`中检查最终合并的资源 2. 检查所有第三方库的`pom.xml`文件是否包含冲突依赖: ```xml <!-- 例:某个aar可能包含 --> <dependencies> <dependency> <groupId>com.google.android.material</groupId> <artifactId>material</artifactId> <version>1.6.0</version> <!-- 冲突版本 --> </dependency> </dependencies> ``` > 💡 **经验提示**:当迁移到AndroidX后,所有`android.support.*`引用都应替换为`androidx.*`[^1]。使用Android Studio的`Refactor > Migrate to AndroidX`可自动完成[^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值