在我开发的应用程序中,我试图从数据库中获取名称,但收到此错误消息:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getImportantForAccessibility()' on a null object reference
这非常令人沮丧。我尝试过使用断点并查看了代码。 Logcat也没有告诉我错误的位置。请帮忙:(
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;
}
}
编辑:这是整个堆栈跟踪:
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)
答案 0 :(得分:5)
您的问题是由于您的适配器使用空引用填充而引起的,正如您在日志中看到的那样:
01-18 13:46:54.906 3542-3542/com.chromepenguinstudios.namedictionary2 D/Favourites﹕ nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
这是由:
写的String logMessage = "";
for (String s : favouriteNames) {
logMessage += s;
}
Log.d("Favourites", logMessage);
Offtopic note:考虑使用StringBuilder或StringBuffer进行字符串追加
然后,当ListView尝试为条目创建视图时,它不能并且它将检索null。
你应该检查你的功能:
// 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
}
当您修复它时,您将能够填充列表。