屏幕方向更改时出现Android NullPointerException或null

arknldoa  于 2023-01-19  发布在  Android
关注(0)|答案(3)|浏览(130)

当应用程序在肖像上时,一切都很好,但当我使用风景时(我创建了应用程序的2个视觉,但只有肖像工作),应用程序突然关闭并显示java.lang.NullPointerException: findViewById(R.id.roll_button) must not be nullUnable to start activity ComponentInfo{MainActivity}: java.lang.NullPointerException
我从互联网上添加了一些解决方案,包括添加android:configchangesandroid:scrrenOrientation="portrait",它没有帮助。
代码如下所示:
主要活动:

class MainActivity : AppCompatActivity() {
        lateinit var diceImage: ImageView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val rollButton: Button = findViewById(R.id.roll_button)!!
        rollButton.setOnClickListener {
            rollDice()
        }
        diceImage = findViewById(R.id.dice_image)
    }

    private fun rollDice() {
        val randomInt = Random().nextInt(6) + 1
        val drawableResource = when (randomInt) {
            1 -> R.drawable.dice_1
            2 -> R.drawable.dice_2
            3 -> R.drawable.dice_3
            4 -> R.drawable.dice_4
            5 -> R.drawable.dice_5
            else -> R.drawable.dice_6
        }
        diceImage.setImageResource(drawableResource)
    }
}

下面的代码是activity_main.xml:(以下大多数都可以)

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:configChanges="orientation|screenSize"
    tools:context=".MainActivity"
    >

    <ImageView
        android:id="@+id/dice_image"
        android:layout_width="123dp"
        android:layout_height="96dp"
        android:layout_marginStart="144dp"
        android:layout_marginTop="112dp"
        android:configChanges="orientation|screenSize"
        android:src="@drawable/empty_dice"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:contentDescription="TODO" />

    <Button
        android:id="@+id/roll_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="6dp"
        android:text="@string/roll"
        android:configChanges="orientation|screenSize"
        app:layout_constraintBottom_toTopOf="@+id/textView2"
        app:layout_constraintStart_toEndOf="@+id/textView2"/>
</android.support.constraint.ConstraintLayout>
q8l4jmvw

q8l4jmvw1#

请添加LogCat错误和LandscapeMode布局详细信息。
我建议你使用下面的解决方案。
使用视图绑定数据绑定避免**findViewById()**在开发中更易于使用。
只需遵循一些步骤
1.在build.gradle应用程序中添加以下行

android {

    buildFeatures {
        viewBinding true

    }
}

2.在父布局中使用此关键字tools:viewBindingIgnore=“true”

<LinearLayout
      
 tools:viewBindingIgnore="true" >
 
</LinearLayout>

1.你的活动的onCreate()是这样的.

private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     binding = ResultProfileBinding.inflate(layoutInflater)
     val view = binding.root
     setContentView(view)
}

1.现在您可以轻松访问所有ID。

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

有关详细信息,请访问https://developer.android.com/topic/libraries/view-binding
对于数据绑定,请访问https://developer.android.com/topic/libraries/data-binding

ygya80vv

ygya80vv2#

永远不要用!!(非空Assert操作符)..没有良好的生产应用程序使用它..问题是,该ID是在文件activity_main中找不到.您是否使用2个不同的XML文件,一个用于横向和一个用于纵向.如果是,只需检查配置中,你得到崩溃有该ID,否则,没有理由崩溃。数据绑定和视图绑定是避免null pouiter异常的好方法

0ejtzxu1

0ejtzxu13#

这个问题的标签之一是Kotlin,这里有一个简单的例子来演示savedInstanceState(),它是一个***非常***简单的老虎机 'game',保存水果图像的状态和分数。

主要活动.kt

// I've missed out the imports, just for the sake of brievity

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var images: IntArray

    private val spinButton by lazy {binding.spinButton}
    private val scoreText by lazy {binding.scoreTextView}
    private val imageViews by lazy {
        listOf<ImageView>(binding.imageView1, binding.imageView2, binding.imageView3)
    }
    private var score = 10

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        images = savedInstanceState?.getIntArray(IMAGES)
            ?: intArrayOf( R.drawable.cherries, R.drawable.cherries, R.drawable.cherries)
        score = savedInstanceState?.getInt(SCORE)
            ?: 10
        drawFruit()
        spinButton.setOnClickListener { drawslotMachine() }
    }
    
// when the screen is rotated (I think onDestroy is called) the app saves images and score in a  
// key value pair, IMAGES and SCORE being the keys     
    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putIntArray(IMAGES, images)
        outState.putInt(SCORE, score)
    }
    
    private fun drawslotMachine() {
        score += 10
        setRandomImages()
        drawFruit()
    }

    private fun drawFruit() {
        for (i in 0..(imageViews.size - 1)) {
            imageViews[i].setImageResource(images[i])
        }
        scoreText.text = score.toString()
    }

    private fun setRandomImages() {
        images = intArrayOf(randomImage(), randomImage(), randomImage())
    }

    private fun randomImage(): Int{
        val r = Random.nextInt(15)
        return when(r){
            in 0..4 -> R.drawable.apple
            in 5..8 -> R.drawable.green_apple
            9 -> R.drawable.cherries
            in 10..12 -> R.drawable.mushroom
            in 13..14 -> R.drawable.orange
            else -> R.drawable.mushroom
        }
    }
}

这是Constants.kt文件,其中包含saveInstanceState的键和一些伪值(“Int Array”和“Score”)。

package com.example.gambling

const val IMAGES = "Int Array"
const val SCORE = "Score"

我犯的一个错误是轻率地接受Android Studios代码完成并使用:
覆盖fun onSaveInstanceState(输出状态:束,输出持久状态:持久性捆绑包)
而不仅仅是:
打开保存示例状态(输出状态:捆绑)
This is also an answer to this question会陷入一些潜在的陷阱也是Joed Goh, this answer is based on this work的***巨大优势***

相关问题