我在尝试将数据从SQLite加载到tableLayout时遇到了一些问题。
DataBaseAdapter.java
protected static final String TAG = "DatabaseAdapter";
private final Context mContext;
private SQLiteDatabase mDb;
private DataBaseHelper mDbHelper;
public DatabaseAdapter(Context context) {
this.mContext = context;
mDbHelper = new DataBaseHelper(mContext);
}
public DatabaseAdapter createDatabase() throws SQLException {
try {
mDbHelper.createDataBase();
Log.e(TAG, "Database Created");
} catch (IOException mIOException) {
Log.e(TAG, mIOException.toString() + " UnableToCreateDatabase");
throw new Error("UnableToCreateDatabase");
}
return this;
}
public SQLiteDatabase open() throws SQLException {
try {
mDbHelper.openDataBase();
mDbHelper.close();
mDb = mDbHelper.getReadableDatabase();
Log.e(TAG, "Database Open");
} catch (SQLException mSQLException) {
Log.e(TAG, "open >>" + mSQLException.toString());
throw mSQLException;
}
return mDb;
}
public void close() {
mDbHelper.close();
}
DataBaseHelper.java
private static String TAG = "DataBaseHelper"; // Tag just for the LogCat
// window
// destination path (location) of our database on device
private static String DB_PATH = "";
private static String DB_NAME = "schoolAssignment";// Database name
private SQLiteDatabase mDataBase;
private final Context mContext;
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 1);// 1? its Database Version
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
this.mContext = context;
}
public void createDataBase() throws IOException {
// If database not exists copy it from the assets
Log.e(TAG, "CreateDataBase()");
boolean mDataBaseExist = checkDataBase();
if (!mDataBaseExist) {
this.getReadableDatabase();
this.close();
try {
// Copy the database from assests
copyDataBase();
Log.e(TAG, "createDatabase database created");
} catch (IOException mIOException) {
throw new Error("ErrorCopyingDataBase");
}
}
}
// Check that the database exists here: /data/data/your package/databases/Database
// Name
private boolean checkDataBase() {
File dbFile = new File(DB_PATH + DB_NAME);
Log.e("dbFile", dbFile + " "+ dbFile.exists());
return dbFile.exists();
}
// Copy the database from assets
private void copyDataBase() throws IOException {
InputStream mInput = mContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream mOutput = new FileOutputStream(outFileName);
byte[] mBuffer = new byte[1024];
int mLength;
while ((mLength = mInput.read(mBuffer)) > 0) {
mOutput.write(mBuffer, 0, mLength);
}
mOutput.flush();
mOutput.close();
mInput.close();
}
// Open the database, so we can query it
public boolean openDataBase() throws SQLException {
String mPath = DB_PATH + DB_NAME;
// Log.v("mPath", mPath);
mDataBase = SQLiteDatabase.openDatabase(mPath, null,
SQLiteDatabase.CREATE_IF_NECESSARY);
// mDataBase = SQLiteDatabase.openDatabase(mPath, null,
// SQLiteDatabase.NO_LOCALIZED_COLLATORS);
return mDataBase != null;
}
@Override
public synchronized void close() {
if (mDataBase != null)
mDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
Exercise.java
TableLayout table_layout;
private SQLiteDatabase mDb;
public Exercise(SQLiteDatabase mDb) {
this.mDb = mDb;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tabhost);
table_layout = (TableLayout) findViewById(R.id.TableLayout);
BuildTable();
}
private void BuildTable() {
try {
String sql = "SELECT * FROM exercise";
Cursor mCur = mDb.rawQuery(sql, null);
if (mCur.getCount() != 0) {
if (mCur.moveToFirst()) {
do {
int rows = mCur.getCount();
int cols = mCur.getColumnCount();
// outer for loop
for (int i = 0; i < rows; i++) {
TableRow row = new TableRow(this);
row.setLayoutParams(new LayoutParams(
LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
// inner for loop
for (int j = 0; j < cols; j++) {
TextView tv = new TextView(this);
tv.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
tv.setGravity(Gravity.CENTER);
tv.setTextSize(18);
tv.setPadding(0, 5, 0, 5);
tv.setText(mCur.getString(j));
row.addView(tv);
}
table_layout.addView(row);
}
} while (mCur.moveToNext());
}
}
} catch (SQLException mSQLException) {
throw mSQLException;
}
但是,我收到错误消息为LogCat:
07-29 22:51:31.221: E/AndroidRuntime(32638): FATAL EXCEPTION: main
07-29 22:51:31.221: E/AndroidRuntime(32638): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{edu.nyp.project/edu.nyp.project.Exercise}: java.lang.InstantiationException: can't instantiate class edu.nyp.project.Exercise; no empty constructor
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1894)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1995)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.app.ActivityThread.access$600(ActivityThread.java:127)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1161)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.os.Handler.dispatchMessage(Handler.java:99)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.os.Looper.loop(Looper.java:137)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.app.ActivityThread.main(ActivityThread.java:4512)
07-29 22:51:31.221: E/AndroidRuntime(32638): at java.lang.reflect.Method.invokeNative(Native Method)
07-29 22:51:31.221: E/AndroidRuntime(32638): at java.lang.reflect.Method.invoke(Method.java:511)
07-29 22:51:31.221: E/AndroidRuntime(32638): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:982)
07-29 22:51:31.221: E/AndroidRuntime(32638): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
07-29 22:51:31.221: E/AndroidRuntime(32638): at dalvik.system.NativeStart.main(Native Method)
07-29 22:51:31.221: E/AndroidRuntime(32638): Caused by: java.lang.InstantiationException: can't instantiate class edu.nyp.project.Exercise; no empty constructor
07-29 22:51:31.221: E/AndroidRuntime(32638): at java.lang.Class.newInstanceImpl(Native Method)
07-29 22:51:31.221: E/AndroidRuntime(32638): at java.lang.Class.newInstance(Class.java:1319)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.app.Instrumentation.newActivity(Instrumentation.java:1026)
07-29 22:51:31.221: E/AndroidRuntime(32638): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1885)
07-29 22:51:31.221: E/AndroidRuntime(32638): ... 11 more
07-29 22:51:45.088: I/Process(32638): Sending signal. PID: 32638 SIG: 9
我确实把我从SQLite数据库浏览器创建的数据库放到了当前项目的assets文件夹中。我不确定为什么错误消息告诉我它无法找到该表。
提前致谢。
答案 0 :(得分:2)
如果使用参数添加构造函数,则default-no args构造函数将不可用。因此,任何使用no-args构造函数创建实例的尝试都将失败。在这里,看起来,Android本身正在尝试使用no-args反射性地创建此类的实例,但由于no-args构造函数不可用,因此无法实例化Exercise类的新对象。您可以尝试提供new no args构造函数,并在此构造函数中初始化sqlLite数据库以避免空指针(只是在空构造函数中初始化mDB)。 像,
public Exercise() {
this.mDb = new DataBaseHelper(this).getReadableDatabase();
}
。 mDb的初始化取决于你想要得到的东西。它可以是可读数据库,可写数据库等。您只需要在此处初始化mDb以使代码正常工作。 如果我是你,我会创建另一个类,这个练习类可以使用并使用SQL相关的新类(作为DAO层),而不是在Exercise类中使用SQLdatabase(假设你的练习类在扩展Activty类中现在)。