简体   繁体   中英

Android RunTimeException can't instantiate class

I am having some problem when trying to load data from SQLite into 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;
    }

However, I am getting the error message as the 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

I did put the database I created from SQLite Database Browser into assets folder of the current project. I not sure why the error message telling me it cant find the table.

Thanks in advance.

If you add constructor with arguments, default-no args constructor wont be available. Hence any attempt to create an instance using no-args constructor will fail. Here, it looks like ,Android itself is trying to create instance of this class reflectively using no-args, but since no-args constructor is not available, it is not able to instantiate new object of Exercise class. You can try providing new no args constructor, and initialize your sqlLite db inside this constructor to avoid null pointer ( just initialize mDB inside empty constructor). something like,

public Exercise() {    
     this.mDb =  new DataBaseHelper(this).getReadableDatabase();  
} 

. The initialization of mDb depends upon what you are trying to get. It could be readable databse, writable database or so forth. You just need to initialize the mDb here to get your code working. If I were you, I would create another class that this Exercise class can use and use SQL related any features on that new class (as DAO layer) rather than using SQLdatabase in Exercise class ( assumption is that your Exercise class in extending Activty class as of now).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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