简体   繁体   English

仅当minifyEnabled并与LifeCycle v 2.1.0一起使用时,应用程序在创建ViewModel时崩溃

[英]App crash on creating ViewModel only when minifyEnabled and with LifeCycle v 2.1.0

My app is crashing on launch with a LinkageError when creating a view model using lazy{} . 使用lazy{}创建视图模型时,我的应用在启动时因LinkageError崩溃。 The crash only happens when: 仅在以下情况下才发生崩溃:

  1. minifyEnabled is set to true in build.gradle, AND minifyEnabled设置为true ,并且
  2. I use ver. 我用ver。 2.1.0 of lifecycle components. 2.1.0生命周期组件。 It works fine with lifecycle-2.0.0 with minifyEnabled 它与带minifyEnabled lifecycle-2.0.0一起minifyEnabled
    def lifecycle_version = '2.1.0'
    implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"

Also, the crash is only happening for one of the view models. 此外,崩溃仅发生在其中一种视图模型上。 Other view models in the same activity that are touched before this one, aren't crashing the app. 在此活动之前接触过的同一活动中的其他视图模型不会使应用程序崩溃。


The crash happens on the second line here: 崩溃发生在第二行:

    private val searchStackViewModel by lazy {
        ViewModelProviders.of(this)[SearchStateViewModel::class.java]
    }

The SearchStateViewModel is: SearchStateViewModel是:

class SearchStateViewModel : ViewModel() {

    // Live data that initialises to empty stack with SearchStack.init
    private val privateStack = MutableLiveData<SearchStack>().apply {
        value = SearchStack()
    }

    // Observable view of search stack so it can't be directly modified
    internal val stateStack : LiveData<SearchStack> = privateStack

    /**
     * Add state to stack
     */
    fun add(searchState: SearchState) {
        val current = privateStack.value ?: SearchStack()
        current.add(searchState)
        privateStack.value = current
    }

    /**
     * Clear stack
     */
    fun clear() {
        val current = privateStack.value ?: SearchStack()
        current.clear()
        privateStack.value = current
    }

    /**
     * Clear stack, then add current state as the only state
     */
    fun clearThenAdd(searchState: SearchState) {
        val current = privateStack.value ?: SearchStack()
        current.clear()
        current.add(searchState)
        privateStack.value = current
    }

    /**
     * Get currentState search state, without changing the stack
     */
    fun currentState(): SearchState {
        return privateStack.value?.last() ?: SearchState()
    }

    /**
     * Return currentState search state, and remove it from the stack
     */
    fun pop(): SearchState {
        val current = privateStack.value ?: SearchStack()
        val poppedState = current.pop()
        privateStack.value = current
        return poppedState
    }
}

SearchStack is just an ArrayList: SearchStack只是一个ArrayList:

class SearchStack : ArrayList<SearchState>() {

    init {
        add(SearchState())
    }


    fun pop(): SearchState = if (lastIndex > 0) removeAt(lastIndex) else last()


    override fun clear() {
        super.clear()
        add(SearchState())
    }


    override fun add(element: SearchState): Boolean {
        if (element == lastOrNull())
            return false
        return super.add(element)
    }
}

And SearchState is a data class: 而且SearchState是一个数据类:

@Parcelize
data class SearchState(
        val searchTerm: String = "",
        val isComplete: Boolean? = null,
        val dueOnly: Boolean = false,
        val aliveOnly: Boolean = true,
        val priority: Char? = null,
        val project: String? = null,
        val priorityMatchType: PriorityMatchType? = null,
        val name: String = "",
        val hideThresholdTasks: Boolean = true,
        val sortOrder: Int = -1,
        val sortOrderString: String? = null
                      ) : Parcelable {

    enum class PriorityMatchType {
        GREATOR,
        LESSOR,
        EXACT
    }

    enum class TaskState {
        DUE,
        PENDING,
        COMPLETED,
        ALL
    }

Stacktrace: 堆栈跟踪:

FATAL EXCEPTION: main
    Process: net.c306.ttsuper, PID: 7380
    java.lang.LinkageError: i.a.a.o.b
1 >>    at net.c306.ttsuper.view.ui.MainActivity$v.b(SourceFile:182)
        at net.c306.ttsuper.view.ui.MainActivity$v.b(SourceFile:159)
        at g.j.a(SourceFile:74)
        at net.c306.ttsuper.view.ui.MainActivity.F(SourceFile)
2 >>    at net.c306.ttsuper.view.ui.MainActivity.c(SourceFile:1839)
        at net.c306.ttsuper.view.ui.MainActivity.a(SourceFile:1993)
        at net.c306.ttsuper.view.ui.MainActivity.a(SourceFile:1967)
        at net.c306.ttsuper.view.ui.MainActivity.onCreate(SourceFile:386)
        at android.app.Activity.performCreate(Activity.java:6251)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
        at android.app.ActivityThread.-wrap11(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Line labeled (1) is the lazy create of ViewModel where the crash happens. 标记为(1)的行是发生崩溃的ViewModel的延迟创建。
Line labeled (2) is the first access of ViewModel that initiates the lazy creation: 标记为(2)的行是对ViewModel的首次访问,它启动了延迟创建:

val lastState = searchStackViewModel.currentState()

I have probably resolved this. 我可能已经解决了。 Turns out that in lifecycle-2.0.0 , the ViewModel class has a public method clear() : 事实证明,在lifecycle-2.0.0 ,ViewModel类具有公共方法clear()

    @MainThread
    final void clear() {
        mCleared = true;
        // Since clear() is final, this method is still called on mock objects
        // and in those cases, mBagOfTags is null. It'll always be empty though
        // because setTagIfAbsent and getTag are not final so we can skip
        // clearing it
        if (mBagOfTags != null) {
            synchronized (mBagOfTags) {
                for (Object value : mBagOfTags.values()) {
                    // see comment for the similar call in setTagIfAbsent
                    closeWithRuntimeException(value);
                }
            }
        }
        onCleared();
    }

My SearchStackViewModel also has a completely unrelated clear() method. 我的SearchStackViewModel也有一个完全不相关的clear()方法。

    /**
     * Clear stack
     */
    fun clear() {
        val current = privateStack.value ?: SearchStack()
        current.clear()
        privateStack.value = current
    }

When minifyEnabled is on, there appears to be a conflict between the two, hence the Linkage error. minifyEnabled启用时,两者之间似乎存在冲突,因此发生了链接错误。 I renamed my method and the crashes stopped. 我重命名了方法,然后崩溃停止了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM