Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Build an Interactive Story App (Retired) Finishing the User Interface Formatting Strings

trying to read from null array

I am trying to follow along with this set of videos. I've done everything the same as the videos. However after the formatting a string video if I try to run my program and input name and click the button the app force crashs. Then in the sdk it states that I am trying to read from a null array. I tried to initilize the array before the startActivty(intent) call but it still gives same message.

6 Answers

Kourosh Raeen
Kourosh Raeen
23,733 Points

Hi William - Can you post your code?

''' public class story {

private page[] mPages;

public void Story() {
    mPages = new page[7];

    mPages[0] = new page(
            R.drawable.page0,
            "On your return trip from studying Saturn's rings, you hear a distress signal that seems to be coming from the surface of Mars. It's strange because there hasn't been a colony there in years. Even stranger, it's calling you by name: \"Help me, %1$s, you're my only hope.\"",
            new choice("Stop and investigate", 1),
            new choice("Continue home to Earth", 2));

    mPages[1] = new page(
            R.drawable.page1,
            "You deftly land your ship near where the distress signal originated. You didn't notice anything strange on your fly-by, but there is a cave in front of you. Behind you is an abandoned rover from the early 21st century.",
            new choice("Explore the cave", 3),
            new choice("Explore the rover", 4));

    mPages[2] = new page(
            R.drawable.page2,
            "You continue your course to Earth. Two days later, you receive a transmission from HQ saying that they have detected some sort of anomaly on the surface of Mars near an abandoned rover. They ask you to investigate, but ultimately the decision is yours because your mission has already run much longer than planned and supplies are low.",
            new choice("Head back to Mars to investigate", 4),
            new choice("Continue home to Earth", 6));

    mPages[3] = new page(
            R.drawable.page3,
            "Your EVA suit is equipped with a headlamp, which you use to navigate the cave. After searching for a while your oxygen levels are starting to get pretty low. You know you should go refill your tank, but there's a very faint light up ahead.",
            new choice("Refill at ship and explore the rover", 4),
            new choice("Continue towards the faint light", 5));

    mPages[4] = new page(
            R.drawable.page4,
            "The rover is covered in dust and most of the solar panels are broken. But you are quite surprised to see the on-board system booted up and running. In fact, there is a message on the screen: \"%1$s, come to 28.543436, -81.369031.\" Those coordinates aren't far, but you don't know if your oxygen will last there and back.",
            new choice("Explore the coordinates", 5),
            new choice("Return to Earth", 6));

    mPages[5] = new page(
            R.drawable.page5,
            "After a long walk slightly uphill, you end up at the top of a small crater. You look around, and are overjoyed to see your favorite android, %1$s-S1124. It had been lost on a previous mission to Mars! You take it back to your ship and fly back to Earth.");

    mPages[6] = new page(
            R.drawable.page6,
            "You arrive home on Earth. While your mission was a success, you forever wonder what was sending that signal. Perhaps a future mission will be able to investigate...");
}

public page getPage(int pageNumber)
{
    return mPages[pageNumber];
}

}

'''

that is my story.class the storyActivity class is:

''' public class storyActivity extends AppCompatActivity {

private story mStory = new story();
private ImageView mImageView;
private TextView mTextView;
private Button mChoiceOne;
private Button mChoiceTwo;
private String mName;

public static final String TAG = storyActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_story);

    Intent intent = getIntent();
    String name = intent.getStringExtra(getString(R.string.key_name));


    Log.d(TAG,name);



    loadPage();

    mImageView = (ImageView) findViewById(R.id.storyImageView);
    mTextView = (TextView) findViewById(R.id.storyTextView);
    mChoiceOne = (Button) findViewById(R.id.choiceButtonOne);
    mChoiceTwo = (Button) findViewById(R.id.choiceTwoButton);


}

private void loadPage()
{
    page page = mStory.getPage(1);

    Drawable drawable = getResources().getDrawable(page.getImageId());
    mImageView.setImageDrawable(drawable);
    mTextView.setText(page.getText());
    String pageText = page.getText();
    String.format(pageText,mName );

    mChoiceOne.setText(page.getChoiceOne().getText());
    mChoiceTwo.setText(page.getChoiceTwo().getText());

}

}

'''

Kourosh Raeen
Kourosh Raeen
23,733 Points

One thing that I notice is that in the loadPage() method where you've declared the page variable the type should be Page with a capital p.

Also, as shown in the video you should replace name with mName. You are also missing the following lines of code:

if (mName == null) {
            mName = "Friend";
}

which go after the line:

mName = intent.getStringExtra(getString(R.string.key_name));

I gave my page class a name of just page so no capitilization of page.

I updated mName but still getting same message of reading from null array.

Kourosh Raeen
Kourosh Raeen
23,733 Points

Can you see what line number the error is referring to and then paste that line of code here?

Caused by: java.lang.NullPointerException: Attempt to read from null array at rabbidwolfinc.signalsfrommars.model.story.getPage(story.java:56) at rabbidwolfinc.signalsfrommars.UI.storyActivity.loadPage(storyActivity.java:55) at rabbidwolfinc.signalsfrommars.UI.storyActivity.onCreate(storyActivity.java:43) at android.app.Activity.performCreate(Activity.java:6237) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)  at android.app.ActivityThread.-wrap11(ActivityThread.java)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)  at android.os.Handler.dispatchMessage(Handler.java:102)  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)

Kourosh Raeen
Kourosh Raeen
23,733 Points

OK, now can you post the code for the Story class?

the story class is the first one listed that is the array intilization and filling.

Kourosh Raeen
Kourosh Raeen
23,733 Points

The call to loadPage() should be at the bottom of onCreate()after you set the widget references. The code in loadPage() needs the references to the widgets, like mTextView, be already available.

still getting the same message

Kourosh Raeen
Kourosh Raeen
23,733 Points

OK. Can you post your new code for StoryActivity, after the few changes you made? Also, can you post the code for the Page class as well since that's the only one I haven't seen yet?

Also, one recommendation. Capitalize all class names. That's what every android/java developer does. Your code becomes much more readable and less chance of confusing class names with variable or method names.

public class page { private int mImageId; private String mText; private choice mChoiceOne; private choice mChoiceTwo; private choice mReturn; private boolean mIsFinal = false;

public int getmImageId() {
    return mImageId;
}

public void setmImageId(int mImageId) {
    this.mImageId = mImageId;
}

public page(int imageId, String text, choice choiceOne, choice choiceTwo)
{
    mImageId = imageId;
    mText = text;
    mChoiceOne = choiceOne;
    mChoiceTwo = choiceTwo;
    mIsFinal = true;
}

public page(int imageId, String text)
{
    mImageId = imageId;
    mText = text;
    mChoiceOne = null;
    mChoiceTwo = null;

}

public int getImageId()
{
    return mImageId;
}
public void setImageId(int id)

{
    mImageId = id;
}
public String getText()
{
    return mText;
}

public void setText(String setterText)
{
    mText = setterText;
}

public choice getChoiceOne()
{
    return mChoiceOne;
}

public choice getChoiceTwo()
{
    return mChoiceTwo;
}


public void setChoiceOne(choice setterChoiceOne)
{
    mChoiceOne = setterChoiceOne;
}

public void setChoiceTwo(choice setterChoiceTwo)
{

    mChoiceTwo = setterChoiceTwo;
}

}

It is no longer giving me the null array as I wasn't intilize the array before I used it. However when I click a choice button it does nothing.

''' public class storyActivity extends AppCompatActivity {

private story mStory = new story();
private ImageView mImageView;
private TextView mTextView;
private Button mChoiceOne;
private Button mChoiceTwo;
private String mName;


public static final String TAG = storyActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_story);

    Intent intent = getIntent();
    String mName = intent.getStringExtra(getString(R.string.key_name));

    if(mName == null)
    {
        mName = "friend";
    }

    Log.d(TAG,mName);
    mStory.Story();
    mImageView = (ImageView) findViewById(R.id.storyImageView);
    mTextView = (TextView) findViewById(R.id.storyTextView);
    mChoiceOne = (Button) findViewById(R.id.choiceButtonOne);
    mChoiceTwo = (Button) findViewById(R.id.choiceTwoButton);

    loadPage();
}

private void loadPage()
{
    page page = mStory.getPage(0);

    Drawable drawable = getResources().getDrawable(page.getImageId());
    mImageView.setImageDrawable(drawable);
    mTextView.setText(page.getText());
    String pageText = page.getText();
    String.format(pageText,mName );

    mChoiceOne.setText(page.getChoiceOne().getText());
    mChoiceTwo.setText(page.getChoiceTwo().getText());

}

}

'''

Kourosh Raeen
Kourosh Raeen
23,733 Points

Clicking choice buttons doesn't do anything since there are no listeners set on the buttons, but that gets fixed in the next video.

On another note, you need to change the following line:

String.format(pageText, mName);

to

pageText = String.format(pageText, mName);

You also need to change the place of the line of code that sets the text on mTextView. I think it works right now but you're calling getText() on page twice and you don't have to if you reorder and change your code to how it is in the video:

String pageText = page.getText();
pageText = String.format(pageText, mName);
mTextView.setText(pageText);

I also have a question. You said you hadn't initialized the array and that's why you got the NullPointerException. Were in your code did you fix that?