-2

I am mainly looking for clarification and advice on this. In the app I am working on I setup a fragment for handling some basic controls and text, and moved the necessary XML from the activities layout file into the fragments layout file, without making any changes. However now when I run the app I get a NULLPOINTEREXCEPTION and it seems to be caused at line 19 in my GameStart activty when I try to set the textView by its ID. I have not changed the ID, only moved it to the fragment layout file, so I have two questions:

1) What exactly is the reason this is happening, because something similar happened before that I resolved but I don't see the reason it was happening in the reference docs on Android Developers

2) Any advice on how to fix this

Below is the GameStart activity, LogCat with the error, and the XML files in question. Thanks in advance, I've spent 2 hours now trying to find this answer.

EDITED FILES/LOGCAT BELOW

LogCat:

12-04 13:48:06.322      826-826/com.saphiric.simproject E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.saphiric.simproject/com.saphiric.simproject.GameStart}: java.lang.NullPointerException
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2137)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:109)
            at com.saphiric.simproject.GameStart.<init>(GameStart.java:25)
            at java.lang.Class.newInstanceImpl(Native Method)
            at java.lang.Class.newInstance(Class.java:1130)
            at android.app.Instrumentation.newActivity(Instrumentation.java:1061)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2128)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
            at android.app.ActivityThread.access$600(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)

Starting Activity (The error occurs when the app tries to start the GameStart activity):

package com.saphiric.simproject;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.View;


public class TitleMenu extends ActionBarActivity {

    public void startGame(View view){
        Intent gameStart = new Intent(this, GameStart.class);
        startActivity(gameStart);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActionBar actionBar = getSupportActionBar();
        actionBar.hide();
        setContentView(R.layout.activity_main_menu);
    }
}

Fragment XML

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- Relative layout to handle main interaction area -->
    <RelativeLayout
        android:id="@+id/relativeLayout"
        android:layout_width="wrap_content"
        android:layout_height="90dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/bg_text">

        <TextView
            android:id="@id/storyText"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:text="@string/story_opening_one"
            android:textColor="@color/black" />

        <Button
            android:id="@+id/advanceButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@id/controlsFragment"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:background="@drawable/button_advance"
            android:onClick="advanceGame" />

        <Button
            android:id="@+id/menuButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_below="@id/advanceButton"
            android:background="@drawable/menu_button" />
    </RelativeLayout>
</RelativeLayout>

Fragment Class:

package com.saphiric.simproject;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * Created by Saphiric on 12/4/14.
 */
public class ControlsFragment extends Fragment {

    /**
     * Fragment Lifecycle Methods
     */

    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        // Inflates the layout resource for the fragment
        return inflater.inflate(R.layout.controls_fragment, container, false);
    }

    @Override
    public void onPause(){

    }
}

GameStart activity:

    package com.saphiric.simproject;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

/**
 * Created by Saphiric on 11/12/14.
 */
public class GameStart extends Activity{

    /**
     * Necessary activity variables
     */
    protected int clickCount = 0;
    TextView storyText = (TextView) findViewById(R.id.storyText);

    /**
     * Sets up and alert dialogue builder for making decisions
     * This will need to be revised during production
     */
    AlertDialog.Builder decisionTime = new AlertDialog.Builder(getApplicationContext());

    /**
     * Handles advancing non character based conversations at the beginning
     * of the story.
     * If the player decides to investigate the scream, then the app loads the appropriate activity, and the same with the
     * decision to leave the scene.
     */
    public void advanceGame(View view){

        clickCount = clickCount + 1; // Increments clickCount by 1 per click

        if (clickCount == 1){
            storyText.setText(R.string.story_opening_two);
        } else if(clickCount == 2){
            decisionTime.setTitle("Decision Time!"); // Sets the title for the decision box
            decisionTime.setCancelable(false); // Sets it so that the decision can not be cancelled.
            decisionTime.setPositiveButton("Investigate",new DialogInterface.OnClickListener() { // Sets up the positive button
                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            });
            decisionTime.setNegativeButton("Leave the scene.",new DialogInterface.OnClickListener() { // Sets up the negative button
                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            });
        }
    }

    /**
     * Android activity methods
     * @param savedInstanceState is the apps savedInstanceState
     */
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game_start);
    }
}

GameStart Layout 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:background="@drawable/bg_school_gate"
    android:orientation="vertical">

    <fragment
        android:id="@+id/controlsFragment"
        android:name="com.saphiric.simproject.ControlsFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:layout="@layout/controls_fragment" />

</RelativeLayout>
Saphiric
  • 81
  • 1
  • 8
  • 2
    possible duplicate of [What is a Null Pointer Exception, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it) (**with small sugettion - yet another question with premature findViewById call**) – Selvin Dec 04 '14 at 17:47

3 Answers3

0

TextView storyText = (TextView) findViewById(R.id.storyText);

This should only be called after you set your contentview. The final result should be:

TextView storyText;

And then on onCreate

setContentView(R.layout.activity_game_start);
storyText = (TextView) findViewById(R.id.storyText);
Pedro Oliveira
  • 20,442
  • 8
  • 55
  • 82
0

No, you don't have any fragment here, read more on How to use fragments.

But that's not your problem it should work the way you did it. The only problem is that you're calling findViewById in your constructor, or even before that.

findViewById only works if you have a UI, so you must do all UI initialization after setContentView in onCreate!

TextView storyText;
...
@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_game_start);
    storyText = (TextView) findViewById(R.id.storyText);
}

Also don't forget to call show() on decisionTime.

TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
0

1) The reason this is happening is that the view has not yet been instantiated at the time you are trying to get it's reference.

2) How to fix it: if you have a Fragment, then you should get a reference to it's View's in the Fragment.onCreateView() method. Then you can setup the Activity to talk to the Fragment to do whatever changes you need to the View.

Leo Landau
  • 1,785
  • 17
  • 25
  • Thank you very much, I didn't even think of that. I am a fairly new programmer so I tend to over think things still. I do have one question though regarding why its not working due to not being instantiated yet. Prior to moving the storyText Id into the fragment XML file, that same code was working, i haven't modified it at all since the fragment setup. Which is probably why I didn't think to move where I tired to get it's reference. Any idea why? – Saphiric Dec 04 '14 at 18:04
  • @sin8292 I'm thinking that your previous layout also had a R.id.storyText element, so you were getting the reference to that one. The clue for this is the lack of a "+" in the storyText xml. – Leo Landau Dec 04 '14 at 18:17
  • It doesn't appear to be, I moved the attempt at getting a reference to the TextView after setting the content view, still crashing in the same manner. Updating the LogCat and addding the code for the rest of the files involved in this particular issue. I really do appreciate this help. – Saphiric Dec 04 '14 at 18:49