简体   繁体   中英

Why am I getting a NullPointerException in this app?

In the app I am developing I am trying to get names out of a database, but am getting this error message:

java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getImportantForAccessibility()' on a null object reference

This is extremely frustrating. I have tried using breakpoints and have looked through the code. The Logcat doesn't tell me where the error is, either. Please help :(

MainActivity code:

package com.chromepenguinstudios.namedictionary2;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity implements       View.OnClickListener,
                                                    TextView.OnEditorActionListener,
                                                    AdapterView.OnItemClickListener {
// Global variables, items, arrays and enums
EditText txt_nameField;                                                                                         // Name field
Button btn_submitName;                                                                                          // Get name info button
Button btn_addToFavourites_main;                                                                                // Add name in textbox to favourites
ListView lst_favourites;                                                                                        // Favourite names list
String name;                                                                                                    // Variable where name is stored

String[] favouriteNames;                                                                                        // This is set later when we get the names from the database


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

    // Initialise variables
    txt_nameField = (EditText)findViewById(R.id.txt_name);
    btn_submitName = (Button)  findViewById(R.id.btn_getName);
    btn_addToFavourites_main = (Button)  findViewById(R.id.btn_addToFavourites_main);
    lst_favourites = (ListView)findViewById(R.id.lst_favourites);

    populateListItemsArray();

    String logMessage = "";

    for (String s : favouriteNames) {
        logMessage += s;
    }

    Log.d("Favourites", logMessage);
    ListAdapter myListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, favouriteNames);
    lst_favourites.setAdapter(myListAdapter);

    // Give widgets listeners and such like
    btn_submitName.setOnClickListener(this);                                                                    // When button is clicked
    btn_addToFavourites_main.setOnClickListener(this);                                                          // When button is clicked
    txt_nameField.setOnEditorActionListener(this);                                                              // When the "Go" button on the textbox is clicked
    lst_favourites.setOnItemClickListener(this);                                                                // When an item on the list is clicked

    populateListView();                                                                                         // Adds the names to the list view
}


@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn_getName:
            try {
                name = txt_nameField.getText().toString();      // Store name in string
                txt_nameField.setText("");                      // When user presses back on other activity they are greeted with a fresh text box

                // Launch GetNameActivity
                Class activity = Class.forName("com.chromepenguinstudios.namedictionary2.GetNameActivity");
                Intent launcher = new Intent(this, activity);
                launcher.putExtra("name", name);
                startActivity(launcher);

            }

            catch (ClassNotFoundException e) {
                e.printStackTrace();
                throw new Error("Error: could not launch GetNameActivity!");
            }

            break;

        case R.id.btn_addToFavourites_main:
            String title            = getString(R.string.dialogue_confirmTitle);
            String messageBefore    = getString(R.string.dialogue_favouritesMessage);
            final String textViewContent  = txt_nameField.getText().toString();

            String messageAfter     = String.format(messageBefore, textViewContent);

            new AlertDialog.Builder(this)
                    .setTitle(title)
                    .setMessage(messageAfter)
                    .setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            addToFavourites(textViewContent);
                        }
                    })
                    .setNegativeButton(getString(R.string.cancel), null)
                    .create()
                    .show();
            break;
    }
}


// When list is clicked - connection set up in onCreate()
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
    String clickedName = String.valueOf(adapterView.getItemAtPosition(position));

}


// When the "Go" button is clicked on the dialogue box
@Override
public boolean onEditorAction(TextView v, int id, KeyEvent event) {
    if (id == EditorInfo.IME_ACTION_GO) {
        btn_submitName.performClick();
        return true;                                                            // Tell Android framework that this succeeded
    }   return false;                                                           // Or failed
}


// Sets the adapter for the listview and populates it
private void populateListView() {
    // Pass in the single_row (styles ListView) and names list
    FavouritesListAdapter adapter = new FavouritesListAdapter(this, R.layout.single_row, favouriteNames);
    lst_favourites.setAdapter(adapter);
}


// Put stuff from database in ListView
private void populateListItemsArray() {
    FavouriteName entries = new FavouriteName(this);                                                                            // Get entries from database with this
    entries.openDB();                                                                                                           // Open the database to write to and read from
    NameResult result = entries.getData();                                                                                      // Get data from database
    favouriteNames = result.getFavouritesAsArray();                                                                             // Convert it to a list
    entries.closeDB();                                                                                                          // Close the database to keep it safe
}


private void addToFavourites(String name) {
    boolean successful = true;                                                                                                  // Used in catch and finally statements

    try {
        FavouriteName entry = new FavouriteName(this);
        entry.openDB();

        boolean nameInDB = entry.createEntry(name);

        if (!nameInDB) {
            createAlert(getString(R.string.error_title), getString(R.string.error_addName));
            successful = false;
        }

        entry.closeDB();

    } catch (Exception ex) {
        successful = false;

        createAlert(getString(R.string.error_title), getString(R.string.error_addName));

    } finally {
        if (successful) {
            createAlert(getString(R.string.success_title), getString(R.string.success_addedName));
        }
    }
}


// Deletes a name from the Favourites list
private void deleteFromFavourites(String name) {
    boolean successful = true;

    try {
        FavouriteName entry = new FavouriteName(this);                                                                          // Entry to be deleted
        entry.openDB();                                                                                                         // Open database
        entry.deleteEntry(name);                                                                                                // Get the entry out of the favourites
    }

    catch (Exception ex) {
        successful = false;
        createAlert(getString(R.string.error_title), getString(R.string.error_addName));
    }

    finally {
        if (successful) {
            createAlert(getString(R.string.error_title), getString(R.string.success_addedName));
        }
    }
}


// Creates an AlertDialog
private void createAlert(String title, String message) {
    new AlertDialog.Builder(this)
            .setTitle(title)                                                    // Title of dialogue box
            .setMessage(message)                                                // Main text
            .setPositiveButton(getString(R.string.ok), null)                                      // OK button
            .create()                                                           // Create the alert
            .show();                                                            // Present it to the user
}


// Controls when an action bar menu item is selected
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    super.onOptionsItemSelected(item);
    switch (item.getItemId()) {
        case R.id.menu_about:

            try {
                // Launch about us activity
                Class<?> activity = Class.forName("com.chromepenguinstudios.namedictionary2.AboutUsActivity");
                Intent launcher = new Intent(this, activity);
                startActivity(launcher);
                }

                catch (ClassNotFoundException ex) {
                    ex.printStackTrace();
                    Log.e("Log error", "Couldn't launch the \"About Us\"         activity!");

                    new AlertDialog.Builder(this)
                            .setTitle(getString(R.string.error_title))
                            .setMessage(getString(R.string.error_aboutUs));
                }

                break;
        }
        return true;
    }

        // Create the action bar menu
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);                                   // Take XML file and model action bar menu based on that
        return true;
    }
}

Edit: Here is the entire stack trace:

01-18 13:46:52.633    3542-3542/com.chromepenguinstudios.namedictionary2     I/art﹕ Late-enabling -Xcheck:jni
01-18 13:46:52.757    3542-3542/com.chromepenguinstudios.namedictionary2     W/ActivityThread﹕ Application com.chromepenguinstudios.namedictionary2 is waiting     for the debugger on port 8100...
01-18 13:46:52.854    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ Sending WAIT chunk
01-18 13:46:52.926    3542-3553/com.chromepenguinstudios.namedictionary2 I/art﹕ Debugger is active
01-18 13:46:53.054    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ Debugger has connected
01-18 13:46:53.054    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:53.256    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:53.456    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:53.657    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:53.857    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:54.057    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:54.258    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:54.458    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ waiting for debugger to settle...
01-18 13:46:54.658    3542-3542/com.chromepenguinstudios.namedictionary2 I/System.out﹕ debugger has settled (1374)
01-18 13:46:54.906    3542-3542/com.chromepenguinstudios.namedictionary2     D/Favourites﹕             nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
    01-18 13:47:00.572    3542-3933/com.chromepenguinstudios.namedictionary2     D/OpenGLRenderer﹕ Render dirty regions requested: true
01-18 13:47:00.735    3542-3542/com.chromepenguinstudios.namedictionary2     D/Atlas﹕ Validating map...
01-18 13:47:00.945    3542-3933/com.chromepenguinstudios.namedictionary2     I/Adreno-EGL﹕ <qeglDrvAPI_eglInitialize:410>: QUALCOMM Build: 10/28/14, c33033c,     Ia6306ec328
01-18 13:47:00.946    3542-3933/com.chromepenguinstudios.namedictionary2 I/OpenGLRenderer﹕ Initialized EGL, version 1.4
01-18 13:47:00.965    3542-3933/com.chromepenguinstudios.namedictionary2 D/OpenGLRenderer﹕ Enabling debug mode 0
01-18 13:47:01.073    3542-3542/com.chromepenguinstudios.namedictionary2 D/AndroidRuntime﹕ Shutting down VM
01-18 13:47:01.075    3542-3542/com.chromepenguinstudios.namedictionary2     E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.chromepenguinstudios.namedictionary2, PID: 3542
    java.lang.NullPointerException: Attempt to invoke virtual method 'int     android.view.View.getImportantForAccessibility()' on a null object reference
            at android.widget.AbsListView.obtainView(AbsListView.java:2360)
            at android.widget.ListView.makeAndAddView(ListView.java:1864)
            at android.widget.ListView.fillDown(ListView.java:698)
            at android.widget.ListView.fillFromTop(ListView.java:759)
        at android.widget.ListView.layoutChildren(ListView.java:1673)
        at android.widget.AbsListView.onLayout(AbsListView.java:2148)
        at android.view.View.layout(View.java:15596)
        at android.view.ViewGroup.layout(ViewGroup.java:4966)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15596)
        at android.view.ViewGroup.layout(ViewGroup.java:4966)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
        at android.view.View.layout(View.java:15596)
        at android.view.ViewGroup.layout(ViewGroup.java:4966)
        at android.support.v7.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:502)
        at android.view.View.layout(View.java:15596)
        at android.view.ViewGroup.layout(ViewGroup.java:4966)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
        at android.view.View.layout(View.java:15596)
        at android.view.ViewGroup.layout(ViewGroup.java:4966)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15596)
        at android.view.ViewGroup.layout(ViewGroup.java:4966)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:573)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:508)
        at android.view.View.layout(View.java:15596)
        at android.view.ViewGroup.layout(ViewGroup.java:4966)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2072)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1829)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Your problem is caused because your adapter is being populated with null references, as you can see in the log:

01-18 13:46:54.906    3542-3542/com.chromepenguinstudios.namedictionary2     D/Favourites﹕             nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull

That is written by:

String logMessage = "";

for (String s : favouriteNames) {
    logMessage += s;
}

Log.d("Favourites", logMessage);

Offtopic note: consider using StringBuilder or StringBuffer for string appends

Then, when the ListView tries to create the views for the entries, it can not and it retrieves null.

You should check your function:

// Put stuff from database in ListView
private void populateListItemsArray() {
    FavouriteName entries = new FavouriteName(this);                                                                            // Get entries from database with this
    entries.openDB();                                                                                                           // Open the database to write to and read from
    NameResult result = entries.getData();                                                                                      // Get data from database
    favouriteNames = result.getFavouritesAsArray();                                                                             // Convert it to a list
    entries.closeDB();                                                                                                          // Close the database to keep it safe
}

When you fix it you'll be able to populate the list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM