button.setOnClickListener() 在设备旋转时导致 Android 应用程序崩溃

问题描述 投票:0回答:1

我正在开发一个项目,当按下按钮时,该项目会用文本更新文本视图。例如,您按 0,文本视图上就会显示 0。当设备改变方向时,例如当用户旋转设备时,应用程序崩溃。

当我注释掉

button0.setOnClickListener(new Buttons(request, "0"));
行时,应用程序不会崩溃。

我已经验证在纵向和横向布局中都有一个 id 为“零”的按钮。

布局存储在:

res/layout/activity_main.xml
res/layout-land/activity_main.xml

当“.setOnclickListener()”代码行未包含在“MainActivity”中时,两种布局中都没有警告或错误消息,并且(再次)两种布局都起作用。

头等舱。 MainActivity.java:

package com.example.myapp;

import android.content.res.Configuration;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

public class MainActivity extends AppCompatActivity {

    Button button0;
    
    TextView request;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);

        request = findViewById(R.id.request);

        // Number Buttons
        button0 = findViewById(R.id.zero);
        button0.setOnClickListener(new Buttons(request, "0"));

        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });
    }

}


第二类。按钮.java:


package com.example.myapp;

import android.view.View;
import android.widget.TextView;

import static androidx.core.content.res.TypedArrayUtils.getText;

public class Buttons implements View.OnClickListener {

    TextView tv;
    String text;


    public Buttons(TextView tv, String input){
        this.tv = tv;
        this.text = input;
    }

    public Buttons(TextView tv){
        this.tv = tv;
        this.text = "";
    }


    @Override
    public void onClick(View view) {
        if (tv.getText().toString().equals("Request")){
            tv.setText(text);
        }
        else {
            String response = tv.getText().toString() + text;
            tv.setText(response);
        }
    }
}

我尝试将其附加到 MainActivity.java 类:

   @Override
    protected void onDestroy() {
      
        button0.setOnClickListener(null);

        super.onDestroy();}

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }

这是 Logcat:

FATAL EXCEPTION: main
    Process: com.example.texascal, PID: 9311
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.texascal/com.example.texascal.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4164)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322)
        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6499)
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6378)
        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:76)
        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:230)
        at android.os.Looper.loop(Looper.java:319)
        at android.app.ActivityThread.main(ActivityThread.java:8919)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
        at com.example.texascal.MainActivity.onCreate(MainActivity.java:82)
        at android.app.Activity.performCreate(Activity.java:8975)
        at android.app.Activity.performCreate(Activity.java:8944)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4146)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4322) 
        at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6499) 
        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6378) 
        at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:76) 
        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2685) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:230) 
        at android.os.Looper.loop(Looper.java:319) 
        at android.app.ActivityThread.main(ActivityThread.java:8919) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) 
2024-07-23 15:21:58.653  9311-9311  Process                 com.example.texascal                 I  Sending signal. PID: 9311 SIG: 9
---------------------------- PROCESS ENDED (9311) for package com.example.texascal ----------------------------


java android xml android-layout activity-lifecycle
1个回答
0
投票

我发现了问题。在学习如何使用 logcat 后,我发现我有针对各种设备尺寸的重复布局,以适应或响应不同的 Android 设备外形尺寸。虽然 id 为零的按钮存在于多个不同的布局中,但并非所有布局都存在。解决方案是验证 0 按钮对于每个布局都有一个 id。

<Button
    ...
    android:text="0"
    android:id="@+id/zero"/>
© www.soinside.com 2019 - 2024. All rights reserved.