我可以在kotlin的另一个类中监视变量的变化吗



Im在fragment1中,如果在从fragment1调用的类中发生事件,我希望转到fragment2。我试过回调函数:Class中的函数调用fragment1中的函数以进入片段,但我收到了这个错误:

Process: com.example.ilmiogioco, PID: 7992java.lang.IllegalStateException: Method addObserver must be called on the main thread
at androidx.lifecycle.LifecycleRegistry.enforceMainThreadIfNeeded(LifecycleRegistry.java:317)
at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:172)
at androidx.savedstate.SavedStateRegistryController.performRestore(SavedStateRegistryController.java:61)
at androidx.navigation.NavBackStackEntry.<init>(NavBackStackEntry.java:88)
at androidx.navigation.NavBackStackEntry.<init>(NavBackStackEntry.java:73)
at androidx.navigation.NavController.navigate(NavController.java:1138)
at androidx.navigation.NavController.navigate(NavController.java:944)
at androidx.navigation.NavController.navigate(NavController.java:877)
at androidx.navigation.NavController.navigate(NavController.java:863)
at androidx.navigation.NavController.navigate(NavController.java:851)
at com.example.ilmiogioco.FullscreenFragmentSolo.follow(FullscreenFragmentSolo.kt:77)
at com.example.ilmiogioco.Solo.SpaceView.update(SpaceView.kt:276)
at com.example.ilmiogioco.Solo.SpaceView.run(SpaceView.kt:120)
at java.lang.Thread.run(Thread.java:919)

编辑:如果在fullscreenfragmentsolo中调用的类空间视图收集了一个丢失的游戏,我有fullscreenflagmentsolo(fragment1(想要在gameoverfragment(fraction2(中。函数follow((被spaceview调用以在fullscreenfragmentsolo中返回(可能这是线程错误(。

 class FullscreenFragmentSolo : Fragment() {
private var spaceView: SpaceView? = null
private lateinit var backgroundMusic: MediaPlayer
private lateinit var window: Window
private var binding: FragmentFullscreenSoloBinding? = null
object size{
    var x = 0
    var y = 0
}

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    (activity as AppCompatActivity?)!!.supportActionBar!!.hide()
    getActivity()?.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    val soundEffects = SoundEffects(requireContext())
    soundEffects.playSound(SoundEffects.backgroundMusic)
    val outMetrics = DisplayMetrics()
    getActivity()?.getWindow()?.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
    window = activity?.getWindow()!!
    window.attributes.width
    window.attributes.height
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
        val display = activity?.display
        display?.getRealMetrics(outMetrics)
    } else {
        @Suppress("DEPRECATION")
        val display = activity?.windowManager?.defaultDisplay
        @Suppress("DEPRECATION")
        display?.getMetrics(outMetrics)
    }
    size.y = outMetrics.heightPixels
    size.x = outMetrics.widthPixels
    backgroundMusic = MediaPlayer.create(requireContext(), R.raw.background_music)
    backgroundMusic.isLooping = true
    backgroundMusic.start()
    val fragmentBinding = FragmentFullscreenSoloBinding.inflate(inflater, container, false)
    binding = fragmentBinding
    fragmentBinding.root
    spaceView = SpaceView(requireContext(), size, this)
    return spaceView
}
fun follow(){
    findNavController().navigate(R.id.action_fullscreenFragmentSolo_to_gameoverFragment)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    binding?.soloFragment = this
}
override fun onResume() {
    super.onResume()
    spaceView?.resume()
}
fun stopFunction() {
    spaceView?.stop()
}
override fun onPause() {
    super.onPause()
    backgroundMusic.release()
    spaceView?.pause()
}
override fun onDestroyView() {
    super.onDestroyView()
    binding = null
}

GameoverFragment:

open class GameoverFragment : Fragment() {
private var binding: GameoverFragmentBinding? = null

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    // Inflate the layout for this fragment
    val fragmentBinding = GameoverFragmentBinding.inflate(inflater, container, false)
    binding = fragmentBinding
    return fragmentBinding.root
    return view
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    binding?.gameoverFragment = this
}
fun Menu(){
    findNavController().navigate(R.id.action_gameoverFragment_to_startFragment)
}
> override fun onDestroyView() {
>     super.onDestroyView()
>     binding = null }

你能帮我吗?

此异常是由于您的代码从主线程以外的线程调用(通过导航(LifecycleRegistry.addObserver所致。您必须确保从主线程调用导航。

follow()功能中对此进行更改

import android.os.Handler
import android.os.Looper
// ...
fun follow() {
    Handler(Looper.getMainLooper()).post {
        findNavController().navigate(R.id.action_fullscreenFragmentSolo_to_gameoverFragment)
    }
}

最新更新