简体   繁体   English

单击Android时的空指针异常(按钮保存到SQLite数据库)

[英]Null pointer exception for on Click Android (Button saves to SQLite Database)

I get a null pointer exception and my app closes when I click on the confirm button the save profile details to sqlite database. 我得到一个空指针异常,并且当我单击确认按钮时,我的应用程序关闭,将配置文件详细信息保存到sqlite数据库。 I have a log of readings that have the same basic coding structure (Obviously difference column names, etc)and works perfectly. 我有一个具有相同基本编码结构(很明显是不同的列名,等等)并且性能完美的读数日志。 I just can't seem to figure out what is wrong. 我似乎无法弄清楚什么地方出了问题。 It says the error is on line 90 of ProfileDetailActivity file but I don't see how as almost exact same structure in Logdetail activity works perfectly!!!! 它说错误在ProfileDetailActivity文件的第90行上,但是我看不到Logdetail活动中几乎完全相同的结构如何完美地工作!!!! Any help would be greatly appreciated , as I'm close to tearing my hair out! 任何帮助将不胜感激,因为我快要把头发扯掉了!

Thanks 谢谢

ProfileDetailActivity 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();
  }

Database content provider 数据库内容提供者

  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");
       }
    }
     }

    } 

Profile table 资料表

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 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)

Honestly, nullpointerexception is one of the simpler bugs to solve, and it's almost always a bug in your own code. 老实说,nullpointerexception是要解决的较简单的错误之一,并且几乎总是您自己代码中的错误。 Go to the line of code that raised the nullpointerexception and think about what could cause this. 转到引发nullpointerexception的代码行,并考虑可能导致这种情况的原因。 I don't know what line 90 in your source is, but for example if it's the following line of code: 我不知道您的源代码中的第90行是什么,但是例如,如果它是以下代码行:

DOB.getText().toString()

then either DOB is null, or DOB.getText() is null. 那么DOB为null,或者DOB.getText()为null。 If you cannot work out which, then print out the values just before that line of code. 如果无法计算出哪个值,则在该行代码之前打印出值。 Then think about what could cause the null pointer, or backtrack through the code to where DOB was (not) initialized or its 'text' property was (not) set. 然后考虑什么可能导致空指针,或回溯到未初始化DOB或未设置其“文本”属性的代码。

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

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