Reputation: 61
I'm writing a basic word scramble app in Android Studio, and have gotten everything laid out and the methods working, but I'm getting a fatal exception when I send it to my debugger.
Here's my java:
package com.example.admin.androidwordscramble;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.util.Random;
import java.util.Scanner;
public class WordScramble extends ActionBarActivity {
EditText playerEdit;
TextView textUpper;
TextView textInstruction;
Button buttonNew;
Button buttonPlay;
String playerInput;
char[] answerWord;
char[] playerWord;
char[] scrambledWord;
final String word1 = "APPLE";
final String word2 = "CLOVE";
final String word3 = "LEMON";
final String word4 = "ONION";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_word_scramble);
initControls(); //Where my logcat says the first error is.
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_word_scramble, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
void initControls() {
playerEdit = (EditText)findViewById(R.id.playerEdit);
textUpper = (TextView)findViewById(R.id.textUpper);
textInstruction = (TextView)findViewById((R.id.textInstruction));
textUpper.setText("Scramble Game");
buttonNew.setOnClickListener(new Button.OnClickListener() //Where the logcat says the second error is.
{
public void onClick
(View v) { newGame();}});
buttonPlay.setOnClickListener(new Button.OnClickListener()
{public void onClick
(View v) { playGame();}});
}
void newGame() {
playerEdit.setText("");
answerWord = toArray(word1);
shuffle(answerWord);
textUpper.setText(scrambledWord.toString());
textInstruction.setText("Unscramble it!");
}
void playGame() {
playerInput = playerEdit.getText().toString();
playerWord = toArray(playerInput);
if(testWord()) {
textUpper.setText(answerWord.toString());
textInstruction.setText("Correct!");
}
else {
textInstruction.setText("Incorrect. Try again!");
}
}
char[] shuffle(char[] answerWord) {
Random rand = new Random();
char[] scrambledWord = new char[5];
for (int i = 0; i < scrambledWord.length; i++)
scrambledWord[i] = answerWord[i];
final int max = 5;
for (int i = 0; i < max; i++) {
int k = rand.nextInt(scrambledWord.length);
int j = rand.nextInt(scrambledWord.length);
char temp = scrambledWord[k];
scrambledWord[k] = scrambledWord[j];
scrambledWord[j] = temp;
}
return scrambledWord;
}
boolean testWord() {
final int max = 5;
int i = 0;
while (i < max) {
if (playerWord[i] != answerWord[i])
return false;
else {
i++;
}
}
return true;
}
char[] toArray(String wordString) {
Scanner read = new Scanner(wordString);
char[] wordArray = new char[5];
for (int i = 0; i < 5; i++) {
wordArray[i] = wordString.charAt(i);
}
return wordArray;
}
}
My XML:
<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:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".WordScramble">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NEW"
android:id="@+id/buttonNew"
android:layout_marginBottom="58dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="47dp"
android:layout_marginStart="47dp" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PLAY"
android:id="@+id/buttonPlay"
android:layout_alignTop="@+id/buttonNew"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="47dp"
android:layout_marginEnd="47dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Unscramble it!"
android:id="@+id/textInstruction"
android:layout_above="@+id/buttonNew"
android:layout_centerHorizontal="true"
android:layout_marginBottom="167dp" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/playerEdit"
android:layout_above="@+id/buttonNew"
android:layout_centerHorizontal="true"
android:layout_marginBottom="75dp"
android:inputType="text"
android:hint="Try here"
android:textIsSelectable="true"
android:capitalize="characters" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="@+id/textUpper"
android:layout_above="@+id/textInstruction"
android:layout_centerHorizontal="true"
android:layout_marginBottom="36dp" />
Log cat states:
E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.admin.androidwordscramble, PID: 2405
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.admin.androidwordscramble/com.example.admin.androidwordscramble.WordScramble}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
....
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.admin.androidwordscramble.WordScramble.initControls(WordScramble.java:67)
at com.example.admin.androidwordscramble.WordScramble.onCreate(WordScramble.java:36)
I've cleaned and rebuilt a couple times, but it still crashes the emulator and spits out an exception in the debugger. Can anyone point out where I went wrong with the button pointing?
Edit: Logcat for when the app froze:
07-29 14:39:00.168 627-653/? E/ActivityManager﹕ ANR in com.example.admin.project03 (com.example.admin.project03/.WordScramble)
PID: 1782
Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago. Wait queue length: 2. Wait queue head age: 13282.2ms.)
Load: 0.95 / 0.57 / 0.23
CPU usage from 7918ms to 0ms ago:
99% 1782/com.example.admin.project03: 99% user + 0% kernel / faults: 3756 minor
2.6% 627/system_server: 0.1% user + 2.5% kernel / faults: 77 minor
1.2% 250/vinput: 0% user + 1.2% kernel
0.1% 8/rcu_preempt: 0% user + 0.1% kernel
0% 96/adbd: 0% user + 0% kernel / faults: 2 minor
0% 245/healthd: 0% user + 0% kernel
0.1% 254/local_gps: 0% user + 0.1% kernel
0% 783/wpa_supplicant: 0% user + 0% kernel
25% TOTAL: 24% user + 0.6% kernel + 0.3% softirq
CPU usage from 2350ms to 2858ms later:
101% 1782/com.example.admin.project03: 101% user + 0% kernel / faults: 200 minor
98% 1782/admin.project03: 98% user + 0% kernel
1.8% 1797/GCDaemon: 1.8% user + 0% kernel
5.8% 627/system_server: 1.9% user + 3.9% kernel / faults: 3 minor
1.9% 639/FinalizerDaemon: 0% user + 1.9% kernel
1.9% 645/SensorService: 0% user + 1.9% kernel
1.9% 653/ActivityManager: 1.9% user + 0% kernel
26% TOTAL: 25% user + 1% kernel
07-29 14:39:00.338 627-1830/? D/OpenGLRenderer﹕ Render dirty regions requested: true
07-29 14:39:00.338 627-653/? D/Atlas﹕ Validating map...
07-29 14:39:00.437 627-1830/? I/OpenGLRenderer﹕ Initialized EGL, version 1.4
07-29 14:39:00.437 627-1830/? D/﹕ HostConnection::get() New Host Connection established 0xafc9b9a0, tid 1830
07-29 14:39:00.532 627-645/? D/Sensors﹕ Client connection accepted (186)
07-29 14:39:00.632 627-1830/? D/OpenGLRenderer﹕ Enabling debug mode 0
07-29 14:39:00.644 627-1830/? W/EGL_emulation﹕ eglSurfaceAttrib not implemented
07-29 14:39:00.644 627-1830/? W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xafca9480, error=EGL_SUCCESS
Edit2: Added a while statement to prevent a crash if playGame was called, but now getting a FATAL NullpointerException right at the while statement.
void playGame() {
while (answerWord != null) {
playerInput = playerEdit.getText().toString();
playerWord = toArray(playerInput);
if (testWord()) {
textUpper.setText(answerWord.toString());
textInstruction.setText("Correct!");
} else {
textInstruction.setText("Incorrect. Try again!");
}
}
}
Upvotes: 0
Views: 1173
Reputation: 2172
Your buttonNew
and buttonPlay
are never initialized before calling the setOnClickListener
, you need to add findViewById
statements, to get a handle to the buttons in the view, giving them the same id
in XML as the variable name does not give you the handle. So, before setting the OnClickListener
you need to add ::
buttonNew = (Button) findViewById(R.id.buttonNew);
buttonPlay = (Button) findViewById(R.id.buttonPlay);
Just like you did for playerEdit
, etc.
All the variables are initialized null
by default, so without finding the view, you are calling setOnClickListener
on null
object, and hence the exception.
Upvotes: 1