Android 在用户输入后尝试在 SQLite 数据库中插入数据时出现 NPE
Android NPE when trying to insert data in SQLite database after user input
我有一个片段可以膨胀三个 EditText
视图的布局。收集用户输入后,我想将该数据保存到我的 SQLite 数据库中。保存按钮位于选项菜单上,并由调用片段的相同 Activity 放大。
当我尝试将数据保存到我的数据库时,出现以下 NPE,
NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
尽管当我单击“保存”时所有三个字段都已填入有效数据。
我也很困惑我的 Fragment 和 Activity 中应该有什么逻辑,目前所有的逻辑都在 Activity 中,而 Fragment 实际上只是扩大了布局。
编辑Activity
public class EditActivity extends ActionBarActivity implements DatePickerDialog.OnDateSetListener{
EditText mTitleText;
EditText mDueDate;
EditText mTaskNotes;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_edit, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.action_save:
insertNewTask(findViewById(R.id.task_title));
return true;
case R.id.action_delete:
startActivity(new Intent(this, MainActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
//do some stuff for example write on log and update TextField on activity
String myFormat = "MM/dd/yy"; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
((EditText) findViewById(R.id.task_due_date)).setText(sdf.format(calendar.getTime()));
}
public void showDatePickerDialog(View v) {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
}
private void insertNewTask(View view) {
Task task = new Task();
//TODO this is horribles and only for test
task.setId("TaskId" + Math.random());
mTitleText = ((EditText) view.findViewById(R.id.task_title));
mDueDate = ((EditText) view.findViewById(R.id.task_due_date));
mTaskNotes = ((EditText) view.findViewById(R.id.task_notes));
task.setTitle(mTitleText.getText().toString());
//Holy Shit do the date dance.
try {
SimpleDateFormat sdf = new SimpleDateFormat();
Date taskDueDate = sdf.parse(mDueDate.getText().toString());
DateTime googleDate = new DateTime(taskDueDate);
task.setDue(googleDate);
} catch (ParseException ex) {
Logger.getLogger("EDITFRAGMENT").log(Level.SEVERE, null, ex);
}
task.setNotes(mTaskNotes.getText().toString());
boolean insertSuccess = new TaskTableController(this).insertRow(task);
if(insertSuccess){
Toast.makeText(this, "Task information was saved.", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "Unable to save task information.", Toast.LENGTH_SHORT).show();
}
}
EditFragment
public class EditFragment extends Fragment {
public EditFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_edit, container, false);
}
任务表控制器
public class TaskTableController extends TaskDbHelper {
public TaskTableController(Context context) {
super(context);
}
/***
*
* @param task
* @return
*/
public boolean insertRow(Task task) {
ContentValues values = new ContentValues();
values.put("_id",task.getId());
values.put("title",task.getTitle());
values.put("due", task.getDue().toString());
values.put("notes", task.getNotes());
SQLiteDatabase db = this.getWritableDatabase();
boolean createSuccessful = db.insert(TaskContract.TaskEntry.TABLE_NAME, null, values) > 0;
db.close();
return createSuccessful;
}
}
我正在调用 insertRow
,它被 insertNewTask
从 OnOptionsItemSelected
包裹在 Activity 中,此时 NPE 被抛出,我的 Toasts 都没有显示。为什么在所有三个字段都填充了数据之后我得到的是空对象引用?有更好的模式可以遵循吗?现在我的片段不包含任何逻辑。
而不是从 Fragment 中检索视图,而是定义 activity 可以调用的方法。示例:
在 onCreate() 中:
MyFragment myf = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.yourid);
当您需要时:
myf.getValueFoo();
myf.getValueBar();
等等
我有一个片段可以膨胀三个 EditText
视图的布局。收集用户输入后,我想将该数据保存到我的 SQLite 数据库中。保存按钮位于选项菜单上,并由调用片段的相同 Activity 放大。
当我尝试将数据保存到我的数据库时,出现以下 NPE,
NullPointerException: Attempt to invoke virtual method 'android.text.Editable android.widget.EditText.getText()' on a null object reference
尽管当我单击“保存”时所有三个字段都已填入有效数据。
我也很困惑我的 Fragment 和 Activity 中应该有什么逻辑,目前所有的逻辑都在 Activity 中,而 Fragment 实际上只是扩大了布局。
编辑Activity
public class EditActivity extends ActionBarActivity implements DatePickerDialog.OnDateSetListener{
EditText mTitleText;
EditText mDueDate;
EditText mTaskNotes;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_edit, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case R.id.action_save:
insertNewTask(findViewById(R.id.task_title));
return true;
case R.id.action_delete:
startActivity(new Intent(this, MainActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
//do some stuff for example write on log and update TextField on activity
String myFormat = "MM/dd/yy"; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
((EditText) findViewById(R.id.task_due_date)).setText(sdf.format(calendar.getTime()));
}
public void showDatePickerDialog(View v) {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
}
private void insertNewTask(View view) {
Task task = new Task();
//TODO this is horribles and only for test
task.setId("TaskId" + Math.random());
mTitleText = ((EditText) view.findViewById(R.id.task_title));
mDueDate = ((EditText) view.findViewById(R.id.task_due_date));
mTaskNotes = ((EditText) view.findViewById(R.id.task_notes));
task.setTitle(mTitleText.getText().toString());
//Holy Shit do the date dance.
try {
SimpleDateFormat sdf = new SimpleDateFormat();
Date taskDueDate = sdf.parse(mDueDate.getText().toString());
DateTime googleDate = new DateTime(taskDueDate);
task.setDue(googleDate);
} catch (ParseException ex) {
Logger.getLogger("EDITFRAGMENT").log(Level.SEVERE, null, ex);
}
task.setNotes(mTaskNotes.getText().toString());
boolean insertSuccess = new TaskTableController(this).insertRow(task);
if(insertSuccess){
Toast.makeText(this, "Task information was saved.", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "Unable to save task information.", Toast.LENGTH_SHORT).show();
}
}
EditFragment
public class EditFragment extends Fragment {
public EditFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_edit, container, false);
}
任务表控制器
public class TaskTableController extends TaskDbHelper {
public TaskTableController(Context context) {
super(context);
}
/***
*
* @param task
* @return
*/
public boolean insertRow(Task task) {
ContentValues values = new ContentValues();
values.put("_id",task.getId());
values.put("title",task.getTitle());
values.put("due", task.getDue().toString());
values.put("notes", task.getNotes());
SQLiteDatabase db = this.getWritableDatabase();
boolean createSuccessful = db.insert(TaskContract.TaskEntry.TABLE_NAME, null, values) > 0;
db.close();
return createSuccessful;
}
}
我正在调用 insertRow
,它被 insertNewTask
从 OnOptionsItemSelected
包裹在 Activity 中,此时 NPE 被抛出,我的 Toasts 都没有显示。为什么在所有三个字段都填充了数据之后我得到的是空对象引用?有更好的模式可以遵循吗?现在我的片段不包含任何逻辑。
而不是从 Fragment 中检索视图,而是定义 activity 可以调用的方法。示例:
在 onCreate() 中:
MyFragment myf = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.yourid);
当您需要时:
myf.getValueFoo();
myf.getValueBar();
等等