0

I know this information is all over the internet, but I can't for the life of me figure out what I'm doing wrong. When I try to run my code it crashes immediately with a null pointer exception, but I can't seem to figure out why that is happening or where it is happening. I imagine I am missing something fairly simple, but I am new to android so I don't know what it is. Here is the code:

MainActivity:

public class MainActivity extends Activity implements GetConnInfoFragment.ConnInfoReceiver {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    GetConnInfoFragment frag = new GetConnInfoFragment();
    fragmentTransaction.add(R.id.mainFragmentContainer, frag);
    fragmentTransaction.commit();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
    ....

GetConnInfoFragment:

public class GetConnInfoFragment extends Fragment {
ConnInfoReceiver ownerActivity; 

@SuppressLint("NewApi")
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Button goButton = (Button) getView().findViewById(R.id.connectButton);
    goButton.setOnClickListener(new View.OnClickListener() {            
        @Override
        public void onClick(View v) {
            EditText portBox = (EditText) v.findViewById(R.id.portBox);
            int port = Integer.parseInt(portBox.getText().toString());
            EditText ipBox = (EditText) v.findViewById(R.id.ipAddressBox);
            String address = ipBox.getText().toString();

            // create sockets, might these be garbage collected ? 
            // in which case the main activity should create them. That makes
            // more sense anyway
            // activate next fragment -- call back up to the main activity to trigger this
            ownerActivity.receiveConnInfo(port, address);
        }
    });

    return inflater.inflate(R.layout.getconninfofragment,  container, false);
}

Here is the error message:

E/AndroidRuntime(1470): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.htpccontrol/com.htpccontrol.MainActivity}: java.lang.NullPointerException

Edit: here is my .xml file for the getConnInfoFragment.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

<EditText
    android:id="@+id/ipAddressBox"
    android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    android:hint="@string/enterIP" />

    <EditText
        android:id="@+id/portBox"
    android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    android:hint="@string/enterPort" />

    <Button 
        android:id="@+id/connectButton"
    android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    android:text="@string/Connect" />


</LinearLayout>
0

2 Answers 2

1

The onClick of the goButton instantiates an EditText. In the next line you parse the text to Integer. A fresh instance of an EditText has no text, so portBox.getText().toString() returns null. The same will happen with the ipBox EditText.

Let the user type something in the EditText, put a text in it with portBox.setText() or set the text in xml with android:text="yourText". Otherwise the code makes no sense. Because the scope of the EditText is only in the onClick method. So you can't work with it outside the method.

To get rid of NPEs while parsing, check for null:

if(portBox.getText() != null){
    port = Integer.parseInt(portBox.getText().toString());
}

Edit:

Your code has a few more flaws. Try this code:

// Class fields
EditText portBox;
EditText ipBox;
@SuppressLint("NewApi")
@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // inflate the layout
    View view = inflater.inflate(R.layout.getconninfofragment,  null, false);

    // get the Views of your inflated layout
    Button goButton = (Button) view.findViewById(R.id.connectButton); 
    portBox = (EditText) v.findViewById(R.id.portBox); // set a text to it like I said
    ipBox = (EditText) v.findViewById(R.id.ipAddressBox);

    goButton.setOnClickListener(new View.OnClickListener() {            
        @Override
        public void onClick(View v) {
           int port;
           String address;

           if(portBox.getText() != null && ipBox.getText != null){
                port = Integer.parseInt(portBox.getText().toString());
                address = ipBox.getText().toString();
                // check if this is valid, I can't see it in the snippets of your code
                ownerActivity.receiveConnInfo(port, address);
           }
        }
    });

    return view; // return the view you inflated
}
6
  • Maybe I'm a bit confused about the way android builds the UI elements. I thought the EditText portBox = ... line was just accessing an already created field. In my xml layout file I have this: <EditText android:id="@+id/portBox" ... I thought that means the field is already created when the fragment is instantiated, and then I can access its data by reading using findViewById(). Also, I know proper form is to sanitize the input but for now I'm just testing some interface ideas and not too worried about that
    – Trevor
    Commented Sep 17, 2013 at 22:02
  • The declaration in the xml layout just makes sure that you can use an EditText in this layout and with this in the Fragment. But you get an instance with EditText portBox = (EditText) v.findViewById(R.id.portBox);. After this line the EditText is instantiated and you can work with it. Commented Sep 17, 2013 at 22:04
  • Ok so I put final EditText ipBox = (EditText) getView().findViewById(R.id.ipAddressBox); final EditText portBox = (EditText) getView().findViewById(R.id.portBox); into the onCreateView() method above setting the onClick listener, but it still gives me the same error
    – Trevor
    Commented Sep 17, 2013 at 22:08
  • Unfortunately that code still doesn't work :(. It is still crashing with a null pointer exception. I put a break point on every line in both GetConnInfoFragment, and when debugging it it gets to Button gobutton = (Button) view.findElementById(R.id.connectButton) it then shows me ActivityThread.performLaunchActivity(ActivityThread$ActivityClientRecord,Intent) line:2209 and finally ZygoteInit$MethodAndArgsCaller.run() line 743 and then crashes. I posted above my .xml file, maybe its a problem in there?
    – Trevor
    Commented Sep 17, 2013 at 22:28
  • Please post the code of your activity layout. Is onCreate the only callback you have overriden? Commented Sep 17, 2013 at 22:35
0

It's hard to remote debug this but you should check if all your variables (like ownerActivity) were initialized or if e.g. portBox.getText() may return null.

A good way is to set a breakpoint the code that you created and start the application for debugging (use "Debug as" not "Run as" in Eclipse). That'll let you step through the code to find the line causing the exception.

1
  • I tried debugging it. I put break points on the lines involving the buttons like you suggested. I put a break point on the lines: Button goButton = ... and the next line. When I step over the first break point it opens another window with the title: ActivityThread.performLaunchActivity(ActivityThread$ActivityClientRecord,Intent) line:2209. And the only thing in this window says "Source not found." This looks like some internal android OS stuff, but I'm not sure what it means relating to my project...
    – Trevor
    Commented Sep 17, 2013 at 22:00

Not the answer you're looking for? Browse other questions tagged or ask your own question.