尝试创建 SQL 数据库时出现 NullpointerException
NullpointerException when trying to create SQL Database
我的应用程序应该从列表中的 Sql 数据库加载条目,但是当我执行它时,我只得到一个 NullPointerException:
01-16 18:35:30.239: E/AndroidRuntime(2254): FATAL EXCEPTION: main
01-16 18:35:30.239: E/AndroidRuntime(2254): Process: com.mobilecartography.tudresdenspeechorganiser, PID: 2254
01-16 18:35:30.239: E/AndroidRuntime(2254): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mobilecartography.tudresdenspeechorganiser/com.mobilecartography.tudresdenspeechorganiser.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper.createDataBase()' on a null object reference
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.access0(ActivityThread.java:144)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.os.Handler.dispatchMessage(Handler.java:102)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.os.Looper.loop(Looper.java:135)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.main(ActivityThread.java:5221)
01-16 18:35:30.239: E/AndroidRuntime(2254): at java.lang.reflect.Method.invoke(Native Method)
01-16 18:35:30.239: E/AndroidRuntime(2254): at java.lang.reflect.Method.invoke(Method.java:372)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
01-16 18:35:30.239: E/AndroidRuntime(2254): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper.createDataBase()' on a null object reference
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.mobilecartography.tudresdenspeechorganiser.CurrentDay.loadPresentations(CurrentDay.java:39)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.mobilecartography.tudresdenspeechorganiser.MainActivity.setCurrentWeek(MainActivity.java:70)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.mobilecartography.tudresdenspeechorganiser.MainActivity.onCreate(MainActivity.java:32)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.Activity.performCreate(Activity.java:5933)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
01-16 18:35:30.239: E/AndroidRuntime(2254): ... 10 more
所以 logcat 和调试器告诉我它在使用我的 dbHelper class 中的方法 createDatabase() 时抛出异常。此方法由 CurrentDay 中的 loadPresentations() 调用(尽管我的数据库文件当前仅包含虚拟数据)。这个助手 class 在另一个具有相同 .db 文件的应用程序上工作正常,所以我认为错误出在其他地方。
无论如何这是我的dbHelper Class(.db文件存储在assets/databases/下的项目中):
package com.mobilecartography.tudresdenspeechorganiser;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
public class DatabaseHelper extends SQLiteAssetHelper {
private static String DB_PATH;
private static String DB_PATH_PREFIX = "/data/data/";
private static String DB_PATH_SUFFIX = "/databases/";
private static String DB_NAME = "exercise_database.db";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public void createDataBase() throws IOException {
DB_PATH = DB_PATH_PREFIX + myContext.getPackageName() + DB_PATH_SUFFIX
+ DB_NAME;
boolean dbExist = checkDataBase();
SQLiteDatabase db_Read = null;
if (dbExist) {
} else {
db_Read = this.getReadableDatabase();
db_Read.close();
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
checkDB = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
checkDB.close();
return true;
} catch (SQLiteException e) {
return false;
}
}
private void copyDataBase() throws IOException {
InputStream assetsDB = myContext.getAssets().open(DB_NAME);
File directory = new File(DB_PATH);
if (directory.exists() == false) {
directory.mkdir();
}
OutputStream dbOut = new FileOutputStream(DB_PATH);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
}
public void openDataBase() throws SQLException {
myDataBase = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
}
public SQLiteDatabase getDataBase() throws SQLException {
myDataBase = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return myDataBase;
}
@Override
public synchronized void close() {
if (myDataBase != null) {
myDataBase.close();
}
super.close();
}
//@Override
//public void onCreate(SQLiteDatabase db) {
//}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
主要activity:
package com.mobilecartography.tudresdenspeechorganiser;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import android.app.Activity;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.ExpandableListView;
import com.mobilecartography.tudresdenspeechorganiser.R;
import com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper;
public class MainActivity extends ListActivity {
ArrayList<CurrentDay> currentweek = new ArrayList<CurrentDay>();
SQLiteDatabase database = null;
Cursor dbCursor;
DatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.dbHelper = new DatabaseHelper(this);
setCurrentWeek();
ExpandableListView listView = (ExpandableListView) findViewById(R.id.listView);
MyExpandableListAdapter adapter = new MyExpandableListAdapter(this,
currentweek);
listView.setAdapter(adapter);
}
//fill list with 7 entrys with dates for the next 7 days, for
//each days query presentations for that specific day from sql database
public void setCurrentWeek() {
Calendar cal = new GregorianCalendar();
CurrentDay day = null;
int numDays = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
int today = cal.get(Calendar.DAY_OF_MONTH);
int currentmonth = cal.get(Calendar.MONTH)+1;
int currentyear = cal.get(Calendar.YEAR);
for (int i = 0; i < 7; i++){
if (today+i > numDays){
for (int h = 0; h < 7 - i; h++){
day = new CurrentDay(1+h, currentmonth+1, currentyear);
}
}
else {
day = new CurrentDay(today+i, currentmonth, currentyear);
}
day.loadPresentations();
currentweek.add(day);
}
}
}
日对象class:
package com.mobilecartography.tudresdenspeechorganiser;
import java.io.IOException;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.format.DateFormat;
import android.widget.ArrayAdapter;
import com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper;
public class CurrentDay {
public int day;
public int month;
public int year;
DatabaseHelper dbHelper;
public List<String> children;
SQLiteDatabase database = null;
Cursor dbCursor;
public CurrentDay(int day, int month, int year) {
this.day = day;
this.month = month;
this.year = year;
}
public void loadPresentations() {
try {
dbHelper.createDataBase();
} catch (IOException ioe) {
}
try {
children = new ArrayList<String>();java.sql.Date(parsedUtilDate.getTime());
database = dbHelper.getDataBase();
dbCursor = database.rawQuery("SELECT university FROM pres_table",
null);
dbCursor.moveToFirst();
int index = dbCursor.getColumnIndex("title");
while (!dbCursor.isAfterLast()) {
String record = dbCursor.getString(index);
children.add(record);
dbCursor.moveToNext();
}
}
finally {
if (database != null) {
dbHelper.close();
}
}
}
}
我一整天都在努力解决这个问题。有人看到解决方案了吗?
您从未在 CurrentDay 中初始化 dbHelper。所以 dbHelper.createDataBase();
例 NPE。
您有 2 个 dbHelper 对象。 1 in MainActivity
设置正确。 CurrentDay
中的另一个 1 会引发您的错误。
试试这个:
day.dbHelper = dbHelper;
day.loadPresentations();
DatabaseHelper dbHelper;
你永远不会像这样初始化它
DatabaseHelper dbHelper = new DatabaseHelper(context);
或者,我认为,您可以将 createDataBase() 和 checkDataBase() 设为静态方法
初始化 dbHelper。
dbHelper = new dbHelper(上下文);
我的应用程序应该从列表中的 Sql 数据库加载条目,但是当我执行它时,我只得到一个 NullPointerException:
01-16 18:35:30.239: E/AndroidRuntime(2254): FATAL EXCEPTION: main
01-16 18:35:30.239: E/AndroidRuntime(2254): Process: com.mobilecartography.tudresdenspeechorganiser, PID: 2254
01-16 18:35:30.239: E/AndroidRuntime(2254): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mobilecartography.tudresdenspeechorganiser/com.mobilecartography.tudresdenspeechorganiser.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper.createDataBase()' on a null object reference
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.access0(ActivityThread.java:144)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.os.Handler.dispatchMessage(Handler.java:102)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.os.Looper.loop(Looper.java:135)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.main(ActivityThread.java:5221)
01-16 18:35:30.239: E/AndroidRuntime(2254): at java.lang.reflect.Method.invoke(Native Method)
01-16 18:35:30.239: E/AndroidRuntime(2254): at java.lang.reflect.Method.invoke(Method.java:372)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
01-16 18:35:30.239: E/AndroidRuntime(2254): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper.createDataBase()' on a null object reference
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.mobilecartography.tudresdenspeechorganiser.CurrentDay.loadPresentations(CurrentDay.java:39)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.mobilecartography.tudresdenspeechorganiser.MainActivity.setCurrentWeek(MainActivity.java:70)
01-16 18:35:30.239: E/AndroidRuntime(2254): at com.mobilecartography.tudresdenspeechorganiser.MainActivity.onCreate(MainActivity.java:32)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.Activity.performCreate(Activity.java:5933)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
01-16 18:35:30.239: E/AndroidRuntime(2254): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
01-16 18:35:30.239: E/AndroidRuntime(2254): ... 10 more
所以 logcat 和调试器告诉我它在使用我的 dbHelper class 中的方法 createDatabase() 时抛出异常。此方法由 CurrentDay 中的 loadPresentations() 调用(尽管我的数据库文件当前仅包含虚拟数据)。这个助手 class 在另一个具有相同 .db 文件的应用程序上工作正常,所以我认为错误出在其他地方。
无论如何这是我的dbHelper Class(.db文件存储在assets/databases/下的项目中):
package com.mobilecartography.tudresdenspeechorganiser;
import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
public class DatabaseHelper extends SQLiteAssetHelper {
private static String DB_PATH;
private static String DB_PATH_PREFIX = "/data/data/";
private static String DB_PATH_SUFFIX = "/databases/";
private static String DB_NAME = "exercise_database.db";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public void createDataBase() throws IOException {
DB_PATH = DB_PATH_PREFIX + myContext.getPackageName() + DB_PATH_SUFFIX
+ DB_NAME;
boolean dbExist = checkDataBase();
SQLiteDatabase db_Read = null;
if (dbExist) {
} else {
db_Read = this.getReadableDatabase();
db_Read.close();
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
checkDB = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
checkDB.close();
return true;
} catch (SQLiteException e) {
return false;
}
}
private void copyDataBase() throws IOException {
InputStream assetsDB = myContext.getAssets().open(DB_NAME);
File directory = new File(DB_PATH);
if (directory.exists() == false) {
directory.mkdir();
}
OutputStream dbOut = new FileOutputStream(DB_PATH);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
}
public void openDataBase() throws SQLException {
myDataBase = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
}
public SQLiteDatabase getDataBase() throws SQLException {
myDataBase = SQLiteDatabase.openDatabase(DB_PATH, null,
SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return myDataBase;
}
@Override
public synchronized void close() {
if (myDataBase != null) {
myDataBase.close();
}
super.close();
}
//@Override
//public void onCreate(SQLiteDatabase db) {
//}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
主要activity:
package com.mobilecartography.tudresdenspeechorganiser;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import android.app.Activity;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.ExpandableListView;
import com.mobilecartography.tudresdenspeechorganiser.R;
import com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper;
public class MainActivity extends ListActivity {
ArrayList<CurrentDay> currentweek = new ArrayList<CurrentDay>();
SQLiteDatabase database = null;
Cursor dbCursor;
DatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.dbHelper = new DatabaseHelper(this);
setCurrentWeek();
ExpandableListView listView = (ExpandableListView) findViewById(R.id.listView);
MyExpandableListAdapter adapter = new MyExpandableListAdapter(this,
currentweek);
listView.setAdapter(adapter);
}
//fill list with 7 entrys with dates for the next 7 days, for
//each days query presentations for that specific day from sql database
public void setCurrentWeek() {
Calendar cal = new GregorianCalendar();
CurrentDay day = null;
int numDays = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
int today = cal.get(Calendar.DAY_OF_MONTH);
int currentmonth = cal.get(Calendar.MONTH)+1;
int currentyear = cal.get(Calendar.YEAR);
for (int i = 0; i < 7; i++){
if (today+i > numDays){
for (int h = 0; h < 7 - i; h++){
day = new CurrentDay(1+h, currentmonth+1, currentyear);
}
}
else {
day = new CurrentDay(today+i, currentmonth, currentyear);
}
day.loadPresentations();
currentweek.add(day);
}
}
}
日对象class:
package com.mobilecartography.tudresdenspeechorganiser;
import java.io.IOException;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.text.format.DateFormat;
import android.widget.ArrayAdapter;
import com.mobilecartography.tudresdenspeechorganiser.DatabaseHelper;
public class CurrentDay {
public int day;
public int month;
public int year;
DatabaseHelper dbHelper;
public List<String> children;
SQLiteDatabase database = null;
Cursor dbCursor;
public CurrentDay(int day, int month, int year) {
this.day = day;
this.month = month;
this.year = year;
}
public void loadPresentations() {
try {
dbHelper.createDataBase();
} catch (IOException ioe) {
}
try {
children = new ArrayList<String>();java.sql.Date(parsedUtilDate.getTime());
database = dbHelper.getDataBase();
dbCursor = database.rawQuery("SELECT university FROM pres_table",
null);
dbCursor.moveToFirst();
int index = dbCursor.getColumnIndex("title");
while (!dbCursor.isAfterLast()) {
String record = dbCursor.getString(index);
children.add(record);
dbCursor.moveToNext();
}
}
finally {
if (database != null) {
dbHelper.close();
}
}
}
}
我一整天都在努力解决这个问题。有人看到解决方案了吗?
您从未在 CurrentDay 中初始化 dbHelper。所以 dbHelper.createDataBase();
例 NPE。
您有 2 个 dbHelper 对象。 1 in MainActivity
设置正确。 CurrentDay
中的另一个 1 会引发您的错误。
试试这个:
day.dbHelper = dbHelper;
day.loadPresentations();
DatabaseHelper dbHelper;
你永远不会像这样初始化它
DatabaseHelper dbHelper = new DatabaseHelper(context);
或者,我认为,您可以将 createDataBase() 和 checkDataBase() 设为静态方法
初始化 dbHelper。 dbHelper = new dbHelper(上下文);