Android学习之通过button单击事件用intent跳转页面程序闪退(Bug)

谷梁永年
2023-12-01

引言

在学习Android开发的过程中,遇到了一些简单的bug。

本次为了设计一个用户登陆界面,页面确实完成了设计,并且单一使用可以正常显示。

可如果再创建一个页面,并设计一个Button去OnClick它,并用Intent去start新创建的页面,就会出现程序闪退。

再三查找问题,综合网上查询所得,得到解决,但随之的,新的Bug又产生了,新的Bug先不考虑,本文重在解决Intent闪退问题(实际上是Button的findViewById()导致的)。

原先代码

创建了三个Activity,第一个主启动的MainActivity.class,对应XML为activity_main.xml,第二个为初次学习Android控件布局用的LoginActivity.class,对应activity_login.xml,第三个为LoginActivity_2.class,对应activity_login_2.xml,是对第一个Login的再优化版本。

单刀直入,不摆出无关的代码了。
MainActivity

    protected void initView() {
        Button loginButton = findViewById(R.id.btn_Login);

        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, LoginActivity_2.class);
                startActivity(intent);
            }
        });
    }
}

activity_main.xml

<Button
        android:id="@+id/btn_Login"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:background="@drawable/bg_login_btn_submit"
        android:text="@string/login_btn_text_login"
        android:textColor="#FFFFFF"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.734" />

再看看登陆界面的XML:
activity_login.xml

<Button
            android:id="@+id/btn_login"
            android:layout_width="0dp"
            android:layout_height="55dp"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="16dp"
            android:background="@drawable/bg_login_btn_submit"
            android:text="@string/login_btn_text_login"
            android:textAlignment="center"
            android:textColor="#B3FFFFFF"
            android:textStyle="bold"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

错误分析

报错信息(空指针异常):
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference

看到这你是不是很快就明白了错误的原因?没错,就是因为两个XML中的Button的ID相同了,从而导致在MainActivity.class中使用Button loginButton = findViewById(R.id.btn_Login);时,系统懵逼了,这是用哪个btn_Login?

至此,本错误就显而易见的可以修改了,只需要将两个xml中的buttonID修改为不同值,再在class里面调用对应的id即可。

修改代码

修改activity_main.xmlButtonid

android:id="@+id/main_btn_Login"

修改activity_login.xmlButtonid

android:id="@+id/activity1_btn_login"

最后,再在使用IntentMainActivity.class修改id获取的对象是main_btn_Login即可。

Button loginButton = findViewById(R.id.main_btn_Login);

其他错误

另外,再说说在查找问题的过程中发现的其他同类型问题。

  1. 本次遇到的,id相同,但xml居然不报错,太神奇了。
  2. 没有注册Activity,也就是在AndroidMainifest.xml里声明,注册如下(非主启动页面):
<activity android:name="com.thdmi.login.LoginActivity" />
  1. 隐式跳转没有添加默认的category,理论上最新版的Android Studio会自动加上。
<category android:name="android.intent.category.LAUNCHER" />
  1. 现象应用出现崩溃异常后未整体退出,应用恢复正常使用后intent跳转Activity跳转失败,Activity生命周期也不执行。分析:应用崩溃后,栈内存在有异常的当前Activity,再次复用时出现了界面闪退问题。解决方案:设置启动模式为singleTask-栈内复用模式
  2. 从活动A跳到活动B,如果用putExtra存入key-value值,在BBundle bun = this.getIntent.getString()方法会报错。解决方案:从login到welcome报错,去掉B类Bundle就能通过。
  3. 外部直接使用findViewById()
private Button loginButton = findViewById(R.id.main_btn_Login);
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

解决方案findViewById()不能优先于super.onCreate(savedInstanceState)setContentView(R.layout.activity_main),修改在之后再进行即可。

综上,好好学习,天天Bug。

 类似资料: