由于在空对象引用上调用虚方法,无法启动列表视图 activity。尖端?
Unable to start a List View activity due to invoking virtual method on null object reference. Tips?
抱歉提出愚蠢且重复的问题。我是 android 编程的新手,正在制作一个可以扫描二维码并将数据保存到 SQLite 数据库并在另一个 activity 的 ListView 中显示的应用程序。
此外,ListView 有一个 "search" 功能,它使用户可以键入文本,从而从列表视图中的项目中调出类似的结果(如果在列表视图中找到)。最后,删除功能会在用户点击项目时从 ListView 中删除该项目。
应用程序运行良好并打开 ListView Activity 显示 ListView 的内容,直到我集成了搜索和删除功能。
该应用程序声明我正在尝试对空对象引用调用虚拟方法。我已经查找了如何解决它,但找不到任何东西。
现在它显示此错误:
07-31 18:52:31.688 2900-2900/app.num.barcodescannerproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.num.barcodescannerproject, PID: 2900
java.lang.RuntimeException: Unable to start activity ComponentInfo{app.num.barcodescannerproject/app.num.barcodescannerproject.ListActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void app.num.barcodescannerproject.CustomCursorAdapter.changeCursor(android.database.Cursor)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access0(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
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:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void app.num.barcodescannerproject.CustomCursorAdapter.changeCursor(android.database.Cursor)' on a null object reference
at app.num.barcodescannerproject.ListActivity.onCreate(ListActivity.java:41)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access0(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
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:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
07-31 18:52:32.968 2900-2900/app.num.barcodescannerproject I/Process: Sending signal. PID: 2900 SIG: 9
下面是 Activity 的代码,它将带有数据的 Intent 发送到 ListView Activity:
public void saveOnClick (View saveButton){
String prescriptionName = scanResult.getText().toString();
if (prescriptionName.length() != 0) {
Intent newIntent = new Intent (this, ListActivity.class);
newIntent.putExtra("tag_person_name", prescriptionName);
startActivity(newIntent);
finish();
}
}
这是具有 ListView、搜索和删除功能的 ListActivity 的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseHelper = new PersonDatabaseHelper(this);
listView = (ListView) findViewById(R.id.list_data);
databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);
customAdapter = new CustomCursorAdapter(ListActivity.this, databaseHelper.getAllData());
listView.setAdapter(customAdapter);
Cursor cursor = databaseHelper.getAllData();
EditText myFilter = (EditText) findViewById(R.id.editText);
myFilter.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
customAdapter.getFilter().filter(s.toString());
}
});
customAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return databaseHelper.fetchDataByName(constraint.toString());
}
});
}
//public void onClickEnterData(View btnAdd) {
// startActivityForResult(new Intent(this, ResultActivity.class), ENTER_DATA_REQUEST_CODE);
//}
// @Override
//protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
// if (requestCode == ENTER_DATA_REQUEST_CODE && resultCode == RESULT_OK) {
// databaseHelper.insertData(data.getExtras().getString("tag_person_name"));
// customAdapter.changeCursor(databaseHelper.getAllData());
// }
// }
private OnItemClickListener listContentOnItemClickListener
= new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Cursor cursor = (Cursor) parent.getItemAtPosition(position);
final int item_id = cursor.getInt(cursor.getColumnIndex(PersonDatabaseHelper.PERSON_TABLE_COLUMN_ID));
String item_name = cursor.getString(cursor.getColumnIndex(PersonDatabaseHelper.PERSON_TABLE_COLUMN_NAME));
AlertDialog.Builder myDialog
= new AlertDialog.Builder(ListActivity.this);
myDialog.setTitle("Delete?");
TextView dialogTxt_id = new TextView(ListActivity.this);
ViewGroup.LayoutParams dialogTxt_idLayoutParams
= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialogTxt_id.setLayoutParams(dialogTxt_idLayoutParams);
dialogTxt_id.setText(String.valueOf(item_id));
TextView dialogC1_id = new TextView(ListActivity.this);
ViewGroup.LayoutParams dialogC1_idLayoutParams
= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialogC1_id.setLayoutParams(dialogC1_idLayoutParams);
dialogC1_id.setText(item_name);
LinearLayout layout = new LinearLayout(ListActivity.this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(dialogTxt_id);
layout.addView(dialogC1_id);
myDialog.setView(layout);
myDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
databaseHelper.delete_byID(item_id);
updateList();
}
});
myDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
}
});
myDialog.show();
}
};
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
databaseHelper.close();
}
private void updateList() {
customAdapter.changeCursor(databaseHelper.getAllData());
}
}
据我所见,错误在这里,在 changeCursor:
databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);
我还注意到,当我删除 changeCursor 时,错误将显示在 setOnItemClickListener 中,说明此虚拟方法也在空对象引用上调用。
我能做些什么吗?我在许多网站上进行了广泛的搜索,但无法在任何地方找到解决方案。也许我是瞎子。
更新:感谢您的帮助,我意识到我没有先初始化 customAdapter。但是,既然我做了,我不断收到两个与 customAdapater 完全相同的 NPE 错误,除了第一个在 setOnItemClickListener 处,另一个在 listView.setAdapter。两者显然也在空对象上调用。然而这一次,与 customAdapter 不同,我真的无法发现错误。有帮助吗?
您正在首次使用 CursorAdapter 后对其进行初始化。这是错误的,因为您首先需要在使用它之前创建 CursorAdapter 对象。
...
databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
/* This line is moved from below to this place i.e before you use the changeCursor method on it*/
customAdapter = new CustomCursorAdapter(ListActivity.this, databaseHelper.getAllData());
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);
...
您收到空指针异常 (NPE),因为您正在使用尚未使用 new 创建的对象运算符
在声明 customAdpater
之前,这一行也应该先行吗?
Cursor cursor = databaseHelper.getAllData();
抱歉提出愚蠢且重复的问题。我是 android 编程的新手,正在制作一个可以扫描二维码并将数据保存到 SQLite 数据库并在另一个 activity 的 ListView 中显示的应用程序。 此外,ListView 有一个 "search" 功能,它使用户可以键入文本,从而从列表视图中的项目中调出类似的结果(如果在列表视图中找到)。最后,删除功能会在用户点击项目时从 ListView 中删除该项目。
应用程序运行良好并打开 ListView Activity 显示 ListView 的内容,直到我集成了搜索和删除功能。 该应用程序声明我正在尝试对空对象引用调用虚拟方法。我已经查找了如何解决它,但找不到任何东西。 现在它显示此错误:
07-31 18:52:31.688 2900-2900/app.num.barcodescannerproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.num.barcodescannerproject, PID: 2900
java.lang.RuntimeException: Unable to start activity ComponentInfo{app.num.barcodescannerproject/app.num.barcodescannerproject.ListActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void app.num.barcodescannerproject.CustomCursorAdapter.changeCursor(android.database.Cursor)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access0(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
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:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void app.num.barcodescannerproject.CustomCursorAdapter.changeCursor(android.database.Cursor)' on a null object reference
at app.num.barcodescannerproject.ListActivity.onCreate(ListActivity.java:41)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.access0(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1351)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
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:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
07-31 18:52:32.968 2900-2900/app.num.barcodescannerproject I/Process: Sending signal. PID: 2900 SIG: 9
下面是 Activity 的代码,它将带有数据的 Intent 发送到 ListView Activity:
public void saveOnClick (View saveButton){
String prescriptionName = scanResult.getText().toString();
if (prescriptionName.length() != 0) {
Intent newIntent = new Intent (this, ListActivity.class);
newIntent.putExtra("tag_person_name", prescriptionName);
startActivity(newIntent);
finish();
}
}
这是具有 ListView、搜索和删除功能的 ListActivity 的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseHelper = new PersonDatabaseHelper(this);
listView = (ListView) findViewById(R.id.list_data);
databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);
customAdapter = new CustomCursorAdapter(ListActivity.this, databaseHelper.getAllData());
listView.setAdapter(customAdapter);
Cursor cursor = databaseHelper.getAllData();
EditText myFilter = (EditText) findViewById(R.id.editText);
myFilter.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
customAdapter.getFilter().filter(s.toString());
}
});
customAdapter.setFilterQueryProvider(new FilterQueryProvider() {
public Cursor runQuery(CharSequence constraint) {
return databaseHelper.fetchDataByName(constraint.toString());
}
});
}
//public void onClickEnterData(View btnAdd) {
// startActivityForResult(new Intent(this, ResultActivity.class), ENTER_DATA_REQUEST_CODE);
//}
// @Override
//protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
// if (requestCode == ENTER_DATA_REQUEST_CODE && resultCode == RESULT_OK) {
// databaseHelper.insertData(data.getExtras().getString("tag_person_name"));
// customAdapter.changeCursor(databaseHelper.getAllData());
// }
// }
private OnItemClickListener listContentOnItemClickListener
= new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Cursor cursor = (Cursor) parent.getItemAtPosition(position);
final int item_id = cursor.getInt(cursor.getColumnIndex(PersonDatabaseHelper.PERSON_TABLE_COLUMN_ID));
String item_name = cursor.getString(cursor.getColumnIndex(PersonDatabaseHelper.PERSON_TABLE_COLUMN_NAME));
AlertDialog.Builder myDialog
= new AlertDialog.Builder(ListActivity.this);
myDialog.setTitle("Delete?");
TextView dialogTxt_id = new TextView(ListActivity.this);
ViewGroup.LayoutParams dialogTxt_idLayoutParams
= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialogTxt_id.setLayoutParams(dialogTxt_idLayoutParams);
dialogTxt_id.setText(String.valueOf(item_id));
TextView dialogC1_id = new TextView(ListActivity.this);
ViewGroup.LayoutParams dialogC1_idLayoutParams
= new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
dialogC1_id.setLayoutParams(dialogC1_idLayoutParams);
dialogC1_id.setText(item_name);
LinearLayout layout = new LinearLayout(ListActivity.this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(dialogTxt_id);
layout.addView(dialogC1_id);
myDialog.setView(layout);
myDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
databaseHelper.delete_byID(item_id);
updateList();
}
});
myDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
// do something when the button is clicked
public void onClick(DialogInterface arg0, int arg1) {
}
});
myDialog.show();
}
};
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
databaseHelper.close();
}
private void updateList() {
customAdapter.changeCursor(databaseHelper.getAllData());
}
}
据我所见,错误在这里,在 changeCursor:
databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);
我还注意到,当我删除 changeCursor 时,错误将显示在 setOnItemClickListener 中,说明此虚拟方法也在空对象引用上调用。
我能做些什么吗?我在许多网站上进行了广泛的搜索,但无法在任何地方找到解决方案。也许我是瞎子。
更新:感谢您的帮助,我意识到我没有先初始化 customAdapter。但是,既然我做了,我不断收到两个与 customAdapater 完全相同的 NPE 错误,除了第一个在 setOnItemClickListener 处,另一个在 listView.setAdapter。两者显然也在空对象上调用。然而这一次,与 customAdapter 不同,我真的无法发现错误。有帮助吗?
您正在首次使用 CursorAdapter 后对其进行初始化。这是错误的,因为您首先需要在使用它之前创建 CursorAdapter 对象。
...
databaseHelper.insertData(getIntent().getExtras().getString("tag_person_name"));
/* This line is moved from below to this place i.e before you use the changeCursor method on it*/
customAdapter = new CustomCursorAdapter(ListActivity.this, databaseHelper.getAllData());
customAdapter.changeCursor(databaseHelper.getAllData());
listView.setOnItemClickListener(listContentOnItemClickListener);
...
您收到空指针异常 (NPE),因为您正在使用尚未使用 new 创建的对象运算符
在声明 customAdpater
之前,这一行也应该先行吗?
Cursor cursor = databaseHelper.getAllData();