简体   繁体   English

为什么在此应用程序中出现NullPointerException?

[英]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. Logcat也不告诉我错误在哪里。 Please help :( 请帮忙 :(

MainActivity code: MainActivity代码:

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 题外话:考虑使用StringBuilder或StringBuffer进行字符串追加

Then, when the ListView tries to create the views for the entries, it can not and it retrieves null. 然后,当ListView尝试为条目创建视图时,它不能,并且检索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. 修复后,您将可以填充列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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