Jackson Hoagland Jackson Hoagland - 2 months ago 17
Android Question

Button.setVisibility crashed Android Application

I have encountered an error in my Android application. When I call setVisible() on pauseB, the application crashes due to pauseB being initialized to null. It's odd because calling setVisible() on startB works just fine. Here is the relevant code:

MainActivity.java

...imports...

public class MainActivity extends AppCompatActivity {

public static boolean toggle=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void beginGame(View v)
{
Button startB= (Button)v.findViewById(R.id.startButton);
startB.setVisibility(View.GONE);

Button pauseB = (Button)v.findViewById(R.id.pauseButton);
pauseB.setVisibility(View.VISIBLE);

rest of method...
}

rest of code...
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.placemultiplebuttons_android_examples.com.MainActivity" >

<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="Start!"
android:onClick="beginGame" />

<Button
android:id="@+id/pauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/startButton"
android:layout_alignBottom="@+id/startButton"
android:layout_toRightOf="@+id/startButton"
android:text="Pause"
android:onClick="pauseGame" />


</RelativeLayout>


Here is the exception given by AndroidStudio:

Exception

FATAL EXCEPTION: main
Process: com.example.jackson.myfirstapp, PID: 2285
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:5198) 
at android.view.View$PerformClick.run(View.java:21147) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setVisibility(int)' on a null object reference
at com.example.jackson.myfirstapp.MainActivity.beginGame(MainActivity.java:29)
at java.lang.reflect.Method.invoke(Native Method) 
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
at android.view.View.performClick(View.java:5198) 
at android.view.View$PerformClick.run(View.java:21147) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5417) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 


Restating the problem, the error happens on the line

pauseB.setVisibility(View.VISIBLE);


For the life of me I cannot figure it out. Any help here is appreciated as I am an Android novice. Thank you so much for your time!

Answer

The reason why you got the crash is,

  1. Click startButton executes beginGame method.
  2. The beginGame method, v argument has startButton Button View.
  3. so your Button pauseB = (Button)v.findViewById(R.id.pauseButton); points R.id.pauseButton inside of startButton Button View.
  4. Crash occurred, because the startButton does not contain pauseButton. The pauseButton View is in Activity not startButton View.

To fix this, declare Buttons globally, and define them in onCreate after the setContentView

Button startB = null;
Button pauseB = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startB = (Button) findViewById(R.id.startButton);
    pauseB = (Button) findViewById(R.id.pauseButton);
}

public void beginGame(View v)
{
    startB.setVisibility(View.GONE);
    pauseB.setVisibility(View.VISIBLE);

    rest of method...
}
Comments