尝试交换活动时应用崩溃

时间:2019-05-29 10:42:31

标签: java android

这是基本的活动交换。

如果我在configureActivitySwap()方法中声明一个本地按钮,则应用不会崩溃:

Button voiceBtn = (findViewById(R.id.goToVoice));

但是我必须在全局范围内声明按钮,以便可以在其他方法中使用该按钮,主要是在应该/不应该按下按钮时激活和停用该按钮。

我还注意到,如果我删除finish();方法并将其替换为其他功能,则应用程序可以正常运行,但是我必须以一种或另一种方式使用finish();方法。

public class RecogActivity extends AppCompatActivity {

    private Button voiceBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        voiceBtn = findViewById(R.id.goToVoice);
        setContentView(R.layout.main_layout);

        // some unrelated code

        configureActivitySwap();
    }

    public void configureActivitySwap(){
        // Button voiceBtn = (findViewById(R.id.goToVoice));

        voiceBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

}

我的运行时错误日志:

    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: tk.gandriks.gaaudiotransform, PID: 23125
        java.lang.RuntimeException: Unable to start activity ComponentInfo{tk.gandriks.gaaudiotransform/tk.gandriks.gaaudiotransform.RecogActivity}: 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:2957)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
            at android.app.ActivityThread.-wrap11(Unknown Source:0)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
            at android.os.Handler.dispatchMessage(Handler.java:105)
            at android.os.Looper.loop(Looper.java:164)
            at android.app.ActivityThread.main(ActivityThread.java:6944)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
         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 tk.gandriks.gaaudiotransform.RecogActivity.configureActivitySwap(RecogActivity.java:140)
            at tk.gandriks.gaaudiotransform.RecogActivity.onCreate(RecogActivity.java:124)
            at android.app.Activity.performCreate(Activity.java:7183)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032) 
            at android.app.ActivityThread.-wrap11(Unknown Source:0) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696) 
            at android.os.Handler.dispatchMessage(Handler.java:105) 
            at android.os.Looper.loop(Looper.java:164) 
            at android.app.ActivityThread.main(ActivityThread.java:6944) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374) 

4 个答案:

答案 0 :(得分:4)

您需要先调用setContentView(),然后再调用voiceBtn = findViewById(R.id.goToVoice);由于您未指定布局,因此findViewById方法将不会获取按钮实例

public class RecogActivity extends AppCompatActivity {

   private Button voiceBtn;

   @Override
   protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);
      // set the layout first
      setContentView(R.layout.YOUR_LAYOUT_XML_FILE_NAME)

      voiceBtn = findViewById(R.id.goToVoice);

      // some unrelated code

      configureActivitySwap();
 }

 public void configureActivitySwap(){
    // Button voiceBtn = (findViewById(R.id.goToVoice));

    voiceBtn.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View view) {
        finish();
    }
  });
}

答案 1 :(得分:1)

请尝试一下)您的// some unrelated code中是否包含setContentView方法?

public class RecogActivity extends AppCompatActivity {

    private Button voiceBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        voiceBtn = findViewById(R.id.goToVoice);

        setContentView(R.layout.some_layout)
        // some unrelated code

        configureActivitySwap();
    }

    public void configureActivitySwap(){
        // Button voiceBtn = (findViewById(R.id.goToVoice));

        voiceBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                finish();
            }
        });
    }

}

您因为findViewById正在展开视图而抓到NPE。在第一种情况下,您一直在findViewById之前致电setContentView,但遇到了异常。在第二种情况下-在configureActivitySwap中,是在setContentView之后。将setContentView移到super.onCreate(savedInstanceState)之后,一切都会正常运行。

答案 2 :(得分:1)

是否在尝试使用findViewById查找视图之前设置布局? setContentView(R.layout.main_layout);

答案 3 :(得分:-2)

voiceBtn = (Button) findViewById(R.id.goToVoice);

使用上述内容在您的onCreate()方法中替换该语句。应该可以。

并使用

super.finish() instead of finish()