我该如何修复这个错误:ticker未初始化



如何修复错误:kotlin.UninitializedPropertyAccessException:lateinit属性ticker尚未初始化

  • 我试着修复它,但它不起作用
  • 它告诉我股票代码还没有被程序化
  • 我该如何修复这个错误,并将股票代码初始化
  • 有人能帮我吗

此活动/按钮的Kotlin代码在此处:

package io.ushowcasedev.classic_tetris.ui
import android.view.MotionEvent.*
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.indication
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.ushowcasedev.classic_tetris.ui.theme.Purple200
import io.ushowcasedev.classic_tetris.ui.theme.Purple500
import kotlinx.coroutines.ObsoleteCoroutinesApi
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.ticker
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun GameButton(
modifier: Modifier = Modifier,
size: Dp,
onClick: () -> Unit = {},
autoInvokeWhenPressed: Boolean = false,
content: @Composable (Modifier) -> Unit = {}
) {
val backgroundShape = RoundedCornerShape(size / 2)
lateinit var ticker: ReceiveChannel<Unit>
val coroutineScope = rememberCoroutineScope()
val pressedInteraction = remember { mutableStateOf<PressInteraction.Press?>(null) }
val interactionSource = MutableInteractionSource()
Box(
modifier = modifier
.shadow(5.dp, shape = backgroundShape)
.size(size = size)
.clip(backgroundShape)
.background(
brush = Brush.verticalGradient(
colors = listOf(
Purple200,
Purple500
),
startY = 0f,
endY = 80f
)
).indication(interactionSource = interactionSource, indication = rememberRipple())
.run {
if (autoInvokeWhenPressed) {
pointerInteropFilter {
when (it.action) {
ACTION_DOWN -> {
coroutineScope.launch {
// Remove any old interactions if we didn't fire stop / cancel properly
pressedInteraction.value?.let { oldValue ->
val interaction = PressInteraction.Cancel(oldValue)
interactionSource.emit(interaction)
pressedInteraction.value = null
}
val interaction = PressInteraction.Press(Offset(50f, 50f))
interactionSource.emit(interaction)
pressedInteraction.value = interaction
}

ticker = ticker(initialDelayMillis = 300, delayMillis = 60)
coroutineScope.launch {
ticker
.receiveAsFlow()
.collect { onClick() }
}
}
ACTION_CANCEL, ACTION_UP -> {
coroutineScope.launch {
pressedInteraction.value?.let {
val interaction = PressInteraction.Cancel(it)
interactionSource.emit(interaction)
pressedInteraction.value = null
}
}
ticker.cancel()
if (it.action == ACTION_UP) {
onClick()
}
}
else -> {
if (it.action != ACTION_MOVE) {
ticker.cancel()
}
return@pointerInteropFilter false
}
}
true
}
} else {
clickable { onClick() }
}
}
) {
content(Modifier.align(Alignment.Center))
}
}

错误:

2022-09-10 17:13:53.656 14169-14169/io.ushowcasedev.classic_tetris E/AndroidRuntime: FATAL EXCEPTION: main
Process: io.ushowcasedev.classic_tetris, PID: 14169
kotlin.UninitializedPropertyAccessException: lateinit property ticker has not been initialized
at io.ushowcasedev.classic_tetris.ui.GameButtonKt$GameButton$2$1.invoke(GameButton.kt:100)
at io.ushowcasedev.classic_tetris.ui.GameButtonKt$GameButton$2$1.invoke(GameButton.kt:69)
at androidx.compose.ui.input.pointer.PointerInteropFilter$pointerInputFilter$1$dispatchToView$3.invoke(PointerInteropFilter.android.kt:309)
at androidx.compose.ui.input.pointer.PointerInteropFilter$pointerInputFilter$1$dispatchToView$3.invoke(PointerInteropFilter.android.kt:294)
at androidx.compose.ui.input.pointer.PointerInteropUtils_androidKt.toMotionEventScope-ubNVwUQ(PointerInteropUtils.android.kt:81)
at androidx.compose.ui.input.pointer.PointerInteropUtils_androidKt.toMotionEventScope-d-4ec7I(PointerInteropUtils.android.kt:35)
at androidx.compose.ui.input.pointer.PointerInteropFilter$pointerInputFilter$1.dispatchToView(PointerInteropFilter.android.kt:294)
at androidx.compose.ui.input.pointer.PointerInteropFilter$pointerInputFilter$1.onPointerEvent-H0pRuoY(PointerInteropFilter.android.kt:229)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:292)
at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:297)
at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:179)
at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:98)
at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:97)
at androidx.compose.ui.platform.AndroidComposeView.sendMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1280)
at androidx.compose.ui.platform.AndroidComposeView.handleMotionEvent-8iAsVTc(AndroidComposeView.android.kt:1230)
at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:1169)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3810)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3810)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3810)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3492)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3810)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:3492)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:756)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1881)
at android.app.Activity.dispatchTouchEvent(Activity.java:3501)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:708)
at android.view.View.dispatchPointerEvent(View.java:13730)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6243)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6021)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5470)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5523)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5489)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5648)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5497)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5705)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5470)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5523)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5489)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5497)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5470)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8611)
2022-09-10 17:13:53.659 14169-14169/io.ushowcasedev.classic_tetris E/AndroidRuntime:     at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8476)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8429)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8726)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:198)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:326)
at android.os.Looper.loop(Looper.java:183)
at android.app.ActivityThread.main(ActivityThread.java:7211)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)

如果没有调试日志,我无法确保它何时抛出异常。但根据提供的信息,它之所以会发生,是因为它最初没有到达ACTION_DOWN块。这里只有您第一次初始化值。当它涉及到ACTION_CANCELACTION_UPelse块而没有在When条件下进入ACTION_DOWN块时,它将抛出此异常,因为您尚未初始化。

你可以尝试几件事。

1( 在这里,您可以将ticker声明为null,并向ticker添加null安全调用。

var ticker: ReceiveChannel<Unit>?=null //(1)
...
Box(
...
if (autoInvokeWhenPressed) {
pointerInteropFilter {
when (it.action) {
ACTION_DOWN -> {
...
ticker = ticker(initialDelayMillis = 300, delayMillis = 60)
coroutineScope.launch {
ticker?.receiveAsFlow()
?.collect { onClick() } //(2)
}
}
ACTION_CANCEL, ACTION_UP -> {
coroutineScope.launch {
pressedInteraction.value?.let {
val interaction = PressInteraction.Cancel(it)
interactionSource.emit(interaction)
pressedInteraction.value = null
}
}
ticker?.cancel() //(3)
if (it.action == ACTION_UP) {
onClick()
}
}
else -> {
if (it.action != ACTION_MOVE) {
ticker?.cancel() //(4)
}
return@pointerInteropFilter false
}
}
true
}
} else {
clickable { onClick() }
}
}
  1. 如果您不想将ticker设置为可为null的值(具有lateinit变量(,每次访问它时都会进行isInitialized检查,如下所示。

    if(::ticker.isInitialized){
    ticker.cancel()
    } 
    
  2. 您可以尝试的另一件事是使用惰性初始化来声明ticker。因此,当第一次访问它时,它将被初始化。

    val ticker: ReceiveChannel<Unit> by lazy { ticker(initialDelayMillis = 300, delayMillis = 60) }
    
  3. 若你们确信它首先会出现ACTION_DOWN,那个么这也可能是第一次合成时它会出现ACTION _DOWN的原因之一。但在重新组合的过程中,它可能会遇到其他阻塞。因此,在重新组合时,先前组合值中的初始值可能会丢失。所以你可以像下面的任何东西一样添加记住。

可为空的股票代码:

var ticker: ReceiveChannel<Unit>? = remember{
mutableStateOf<ReceiveChannel<Unit>?>(null)
}

不可为空的股票代码:

var ticker: ReceiveChannel<Unit> = remember{
mutableStateOf<ReceiveChannel<Unit>>(ticker(initialDelayMillis = 300, delayMillis = 60))
}

如果这些都不起作用,请在when-block条件中添加调试语句,并在此处发布日志。

相关内容

  • 没有找到相关文章

最新更新