我得到一个空指针异常,当我点击确认按钮保存配置文件详细信息到sqlite数据库时我的应用程序关闭。我有一个读数记录,具有相同的基本编码结构(明显不同的列名称等),并且工作完美。我似乎无法弄清楚出了什么问题。它说错误是在ProfileDetailActivity文件的第90行,但我没有看到如何在Logdetail活动中几乎完全相同的结构完美运行!!!!任何帮助都将非常感激,因为我已经接近撕裂了我的头发!
由于
ProfileDetailActivity
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import michelle.glucose.contentprovider.MyLogContentProvider;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
/*
* TodoDetailActivity allows to enter a new todo item
* or to change an existing
*/
public class ProfileDetailActivity extends Activity {
private EditText sms;
private EditText email ;
private EditText name;
private EditText DOB;
public TextView textView1;
public TextView textView2 ;
private Spinner type;
private Spinner units;
private Spinner Gender;
private EditText max;
private EditText min;
private Uri progUri;
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.pro_pref);
textView1 = (TextView) findViewById(R.id.textView1);
textView2 = (TextView) findViewById(R.id.textView2);
type = (Spinner) findViewById(R.id.type);
units = (Spinner) findViewById(R.id.units);
Gender = (Spinner) findViewById(R.id.Gender);
max = (EditText) findViewById(R.id.max);
min = (EditText) findViewById(R.id.min);
sms = (EditText) findViewById(R.id.sms);
email = (EditText) findViewById(R.id.Email);
DOB = (EditText) findViewById(R.id.dob);
name = (EditText) findViewById(R.id.name);
Button confirmButton = (Button) findViewById(R.id.Confirm);
Bundle extras = getIntent().getExtras();
// Check from the saved Instance
progUri = (bundle == null) ? null : (Uri) bundle
.getParcelable(MyLogContentProvider.CONTENT_ITEM_TYPE);
// Or passed from the other activity
if (extras != null) {
progUri = extras
.getParcelable(MyLogContentProvider.CONTENT_ITEM_TYPE);
fillData(progUri);
}
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (TextUtils.isEmpty(DOB.getText().toString())) { SAYS ERROR HERE???
makeToast();
} else {
setResult(RESULT_OK);
finish();
}
}
});
}
public void fillData(Uri uri) {
String[] projection = {ProTable.COLUMN_NAME,ProTable.COLUMN_DOB,
ProTable.COLUMN_GENDER,ProTable.COLUMN_UNIT, ProTable.COLUMN_MIN,ProTable.COLUMN_MAX,
ProTable.COLUMN_TYPE, ProTable.COLUMN_EMAIL,ProTable.COLUMN_NUMBER,
ProTable.COLUMN_ID };
Cursor cursor = getContentResolver().query(uri, projection, null, null,
null);
if (cursor != null) {
cursor.moveToFirst();
String idstr = cursor.getString(cursor.getColumnIndexOrThrow(ProTable.COLUMN_ID));
String u = cursor.getString(cursor
.getColumnIndexOrThrow(ProTable.COLUMN_UNIT));
for (int i = 0; i < units.getCount(); i++) {
String s = (String) units.getItemAtPosition(i);
if (s.equalsIgnoreCase(u))
units.setSelection(i);
}
String g = cursor.getString(cursor.getColumnIndexOrThrow(ProTable.COLUMN_GENDER));
for (int i = 0; i < Gender.getCount(); i++) {
String s = (String) Gender.getItemAtPosition(i);
if (s.equalsIgnoreCase(g)) {
Gender.setSelection(i);
}
}
String t = cursor.getString(cursor.getColumnIndexOrThrow(ProTable.COLUMN_TYPE));
for (int i = 0; i < type.getCount(); i++) {
String s = (String) type.getItemAtPosition(i);
if (s.equalsIgnoreCase(t)) {
type.setSelection(i);
}
}
name.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ProTable.COLUMN_NAME)));
DOB.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ProTable.COLUMN_DOB)));
min.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ProTable.COLUMN_MIN)));
max.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ProTable.COLUMN_MAX)));
email.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ProTable.COLUMN_EMAIL)));
sms.setText(cursor.getString(cursor
.getColumnIndexOrThrow(ProTable.COLUMN_NUMBER)));
// Always close the cursor
cursor.close();}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putParcelable(MyLogContentProvider.CONTENT_ITEM_TYPE, progUri);
}
@Override
protected void onPause() {
super.onPause();
saveState();
}
private void saveState() {
String t = (String) type.getSelectedItem();
String u = (String) units.getSelectedItem();
String g = (String) Gender.getSelectedItem();
String n = name.getText().toString();
String d = DOB.getText().toString();
String mi = min.getText().toString();
String ma = max.getText().toString();
String e = email.getText().toString();
String s = sms.getText().toString();
// Only save if either summary or description
// is available
if (d.length() ==0) {
return;
}
ContentValues values = new ContentValues();
values.put(ProTable.COLUMN_NAME, n);
values.put(ProTable.COLUMN_DOB, d);
values.put(ProTable.COLUMN_GENDER, g);
values.put(ProTable.COLUMN_UNIT, u);
values.put(ProTable.COLUMN_TYPE, t);
values.put(ProTable.COLUMN_MIN, mi);
values.put(ProTable.COLUMN_MAX, ma);
values.put(ProTable.COLUMN_EMAIL, e);
values.put(ProTable.COLUMN_NUMBER, s);
if (progUri == null) {
// New log
progUri = getContentResolver().insert(MyLogContentProvider.CONTENT_URI, values);
} else {
// Update log
getContentResolver().update(progUri, values, null, null);
}
}
private void makeToast() {
Toast.makeText(ProfileDetailActivity.this, "Please maintain a glucose log",
Toast.LENGTH_LONG).show();
}
数据库内容提供商
import java.util.Arrays;
import java.util.HashSet;
import michelle.glucose.ProTable;
import michelle.glucose.ProfileDatabaseHelper;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
public class MyProfileContentProvider extends ContentProvider {
// database
private ProfileDatabaseHelper database;
// Used for the UriMacher
private static final int PRO = 10;
private static final int PROD = 20;
private static final String AUTHORITY =
"michelle.glucose.contentprovider.MyProfileContentProvider";
private static final String BASE_PATH = "pros";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
+ "/pros";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
+ "/pro";
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, BASE_PATH, PRO);
sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", PROD);
}
@Override
public boolean onCreate() {
database = new ProfileDatabaseHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Uisng SQLiteQueryBuilder instead of query() method
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
// Check if the caller has requested a column which does not exists
checkColumns(projection);
// Set the table
queryBuilder.setTables(ProTable.TABLE_PRO);
int uriType = sURIMatcher.match(uri);
switch (uriType) {
case PRO:
break;
case PROD:
// Adding the ID to the original query
queryBuilder.appendWhere(ProTable.COLUMN_ID + "="
+ uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
// Make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
long id = 0;
switch (uriType) {
case PRO:
id = sqlDB.insert(ProTable.TABLE_PRO, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH + "/" + id);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case PRO:
rowsDeleted = sqlDB.delete(ProTable.TABLE_PRO, selection,
selectionArgs);
break;
case PROD:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(ProTable.TABLE_PRO,
ProTable.COLUMN_ID + "=" + id,
null);
} else {
rowsDeleted = sqlDB.delete(ProTable.TABLE_PRO,
ProTable.COLUMN_ID + "=" + id
+ " and " + selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case PRO:
rowsUpdated = sqlDB.update(ProTable.TABLE_PRO,
values,
selection,
selectionArgs);
break;
case PROD:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = sqlDB.update(ProTable.TABLE_PRO,
values,
ProTable.COLUMN_ID + "=" + id,
null);
} else {
rowsUpdated = sqlDB.update(ProTable.TABLE_PRO,
values,
ProTable.COLUMN_ID + "=" + id
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void checkColumns(String[] projection) {
String[] available = {ProTable.COLUMN_NAME,ProTable.COLUMN_DOB,
ProTable.COLUMN_GENDER,ProTable.COLUMN_TYPE,ProTable.COLUMN_MIN,
ProTable.COLUMN_MAX,ProTable.COLUMN_UNIT,
ProTable.COLUMN_NUMBER,
ProTable.COLUMN_EMAIL,
ProTable.COLUMN_ID };
if (projection != null) {
HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
// Check if all columns which are requested are available
if (!availableColumns.containsAll(requestedColumns)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
}
个人资料表
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class ProTable {
private static final String DATABASE_NAME = "protable.db";
private static final int DATABASE_VERSION = 1;
private ProfileDatabaseHelper psqLiteHelper;
private SQLiteDatabase pdb;
private Context context;
// Database table
public static final String TABLE_PRO = "pro";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_DOB = "dob";
public static final String COLUMN_GENDER = "gender";
public static final String COLUMN_TYPE = "type";
public static final String COLUMN_GLU = "glu";
public static final String COLUMN_MIN = "min";
public static final String COLUMN_MAX = "max";
public static final String COLUMN_EMAIL = "email";
public static final String COLUMN_UNIT = "unit";
public static final String COLUMN_NUMBER = "number";
// Database creation SQL statement
private static final
String DATABASE_CREATE = "create table "
+ TABLE_PRO
+ "("
+ COLUMN_ID + " integer primary key autoincrement, "
+ COLUMN_NAME + " text not null, "
+ COLUMN_DOB + " text not null,"
+ COLUMN_GENDER + " text not null,"
+ COLUMN_TYPE + " text not null,"
+ COLUMN_MIN + " text not null,"
+ COLUMN_MAX + " text not null,"
+ "COLUMN_UNIT" + "text not null,"
+ COLUMN_EMAIL + " text not null,"
+ COLUMN_NUMBER + " text not null"
+ ");";
public ProTable(Context ctx) {
this.context = ctx;
psqLiteHelper = new ProfileDatabaseHelper(context);
}
public ProTable openToRead() throws android.database.SQLException {
psqLiteHelper = new ProfileDatabaseHelper(context, DATABASE_NAME, null,
DATABASE_VERSION);
pdb = psqLiteHelper.getReadableDatabase();
return this; }
public Cursor getEmail (String email) throws android.database.SQLException{
Cursor mCursor
= pdb.query(TABLE_PRO, new String[] {COLUMN_ID, COLUMN_EMAIL },
COLUMN_EMAIL + "=" + email , null, null, null, null, null);
if (mCursor != null ){
mCursor.moveToFirst();
}
return mCursor;
}
public String getSMS () throws android.database.SQLException{
Cursor mCursor
= pdb.query(TABLE_PRO, new String[] {COLUMN_ID, COLUMN_NUMBER },
COLUMN_NUMBER + "=" + COLUMN_NUMBER, null, null, null, null, null);
if (mCursor != null ){
mCursor.moveToFirst();
}String number =mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_NUMBER));
return number;
}
public static void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
public static void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
Log.w(ProTable.class.getName(), "Upgrading database from version "
+ oldVersion + " to " + newVersion
+ ", which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS " + TABLE_PRO);
onCreate(database);
}
}
DATABASE HELPER CLASSS
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class ProfileDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "protable.db";
private static final int DATABASE_VERSION = 1;
public ProfileDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public ProfileDatabaseHelper(Context context, String databaseName,
CursorFactory factory, int databaseVersion) {
super(context, databaseName , factory, databaseVersion);
}
public ProfileDatabaseHelper(Context context, String databaseName,
Object factory, int databaseVersion) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Method is called during creation of the database
@Override
public void onCreate(SQLiteDatabase database) {
ProTable.onCreate(database);
}
// Method is called during an upgrade of the database,
// e.g. if you increase the database version
@Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
ProTable.onUpgrade(database, oldVersion, newVersion);
}
}
logcat的
E/AndroidRuntime(3797):FATAL EXCEPTION: main
E/AndroidRuntime(3797): java.lang.NullPointerException
E/AndroidRuntime(3797):at michelle.glucose.ProfileDetailActivity$1.onClick(ProfileDetailActivity.java:90)
E/AndroidRuntime(3797):at android.view.View.performClick(View.java:4204)
E/AndroidRuntime(3797):at android.view.View$PerformClick.run(View.java:17355)
E/AndroidRuntime(3797):at android.os.Handler.handleCallback(Handler.java:725)
E/AndroidRuntime(3797): at android.os.Handler.dispatchMessage(Handler.java:92)
E/AndroidRuntime(3797): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(3797): at android.app.ActivityThread.main(ActivityThread.java:5041)
E/AndroidRuntime(3797): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(3797): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(3797): at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime(3797): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime(3797): at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:0)
老实说,nullpointerexception是要解决的更简单的bug之一,它几乎总是你自己代码中的一个bug。转到引发nullpointerexception的代码行,并考虑可能导致此问题的原因。我不知道你的来源中的第90行是什么,但是例如,如果它是以下代码行:
DOB.getText().toString()
然后DOB为null,或者DOB.getText()为null。如果你无法解决哪个问题,那么就在该代码行之前打印出值。然后考虑一下可能导致空指针的原因,或者通过代码回溯到DOB(未)初始化或其“text”属性设置(未)的位置。