Android RunTimeException无法实例化类

时间:2014-07-29 14:57:07

标签: java android sqlite

我在尝试将数据从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文件夹中。我不确定为什么错误消息告诉我它无法找到该表。

提前致谢。

1 个答案:

答案 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类中现在)。