[英]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: 仅在以下情况下才发生崩溃:
minifyEnabled
is set to true
in build.gradle, AND minifyEnabled
设置为true
,并且 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.