0

我有随机数生成器。我需要使用线程将随机数输入到 sqlite 数据库中。我编写了这段代码,但几次后它会关闭应用程序。我是 android 新手,我对此感到困惑,我必须完成这在接下来的 2 天内请帮助我做到这一点这是我的第一次 sqlite 体验(我删除了一些代码部分,因为超出了字符限制,也很抱歉发布整个代码,因为我确定哪个是错误的部分)

我的数据库类

   private static final int DATABASE_VERSION = 6;

    protected Dbhelper ourhelper;
    protected final Context ourcontext;
    protected SQLiteDatabase ourdatabase;

    protected static class Dbhelper extends SQLiteOpenHelper {

        public Dbhelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);

        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub


            db.execSQL("CREATE TABLE " + STATUS_TABLE + ");

            db.execSQL("CREATE TABLE " + AVE_STATUS_TABLE + );

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub

            db.execSQL("DROP TABLE IF EXISTS "+STATUS_TABLE);
            db.execSQL("DROP TABLE IF EXISTS "+AVE_STATUS_TABLE);


            onCreate(db);
        }

    }

    public DatabaseClass(Context c) {
        ourcontext = c;

    } 

我在单独的类中编写了查询

public class DB_queryClass extends DatabaseClass {

    private static final int MAX_ROW_STA = 4;
    private static final int MAX_ROW_AVESTA = 4;
    private static final int AVE_PER = 3;
    private static final int MAX_ROW_DEFECT = 10;

    // private static final double AVE_NUM = 4.0;

    public DB_queryClass(Context c) {
        super(c);


    }

    public DatabaseClass open() throws SQLException {

        ourhelper = new Dbhelper(ourcontext);
        ourdatabase = ourhelper.getWritableDatabase();

        return this;

    }

    // Database close method
    public void close() {

        ourhelper.close();

    }

// Data Entry method to STATUS table
    public long enterStatusData(int vID, String date, String time, String fuel,
            String mafr, String odo, String speed, String torque, String eload,
            String gpsX, String gpsY, String PID) {
        // TODO Auto-generated method stub

        if (rowCount(STATUS_TABLE) > MAX_ROW_STA) {

            deleteFirstEntry_Status();
        }
        if (rowCount(STATUS_TABLE) > 0) {
            if (getdata_sta_last() % AVE_PER == 0) {

                enterAveStatusData();
            }
        }

        if (!PID.equals("0")) {
            enterDefect(date, time, PID);
        }
        ContentValues cv = new ContentValues();


        return ourdatabase.insert(STATUS_TABLE, null, cv);

    }
// Data Entry method to Average STATUS table
    public long enterAveStatusData() {

        if (rowCount(AVE_STATUS_TABLE) > MAX_ROW_AVESTA) {
            deleteFirstEntry_AveStatus();
        }

        String[] columns = new String[] { KEY_VID, KEY_DATE, KEY_TIME,
                KEY_MAFR, KEY_FUEL, KEY_ELOAD, KEY_SPEED, KEY_TORQUE, KEY_GPSX,
                KEY_GPSY, KEY_ODO, KEY_PID };

        Cursor c = ourdatabase.query(STATUS_TABLE, columns, null, null, null,
                null, null);

        c.moveToLast();

        int iVid = c.getColumnIndex(KEY_VID);

        int iTime = c.getColumnIndex(KEY_TIME);
        int iDate = c.getColumnIndex(KEY_DATE);
        int iFuel = c.getColumnIndex(KEY_FUEL);
        int iCo2 = c.getColumnIndex(KEY_MAFR);
        int iOdo = c.getColumnIndex(KEY_ODO);
        int iSpeed = c.getColumnIndex(KEY_SPEED);
        int iTorque = c.getColumnIndex(KEY_TORQUE);
        int ieload = c.getColumnIndex(KEY_ELOAD);
        int ipid = c.getColumnIndex(KEY_PID);

        String Vid = c.getString(iVid);
        double Sspeed = 0;
        int sco2 = 0;
        int storque = 0;
        int seload = 0;
        String Sdate = c.getString(iDate);
        String Stime = c.getString(iTime);
        String Fuel = c.getString(iFuel);
        String Spid = c.getString(ipid);
        String Sodo = c.getString(iOdo);
        int AVE_NUM = 1;
        if (rowCount(STATUS_TABLE) > 0)
            AVE_NUM = rowCount(STATUS_TABLE);

        for (c.moveToLast(); !c.isBeforeFirst(); c.moveToPrevious()) {
            Sspeed = Sspeed + c.getDouble(iSpeed);
            sco2 = sco2 + c.getInt(iCo2);
            storque = storque + c.getInt(iTorque);
            seload = seload + c.getInt(ieload);
        }
        c.close();

        return ourdatabase.insert(AVE_STATUS_TABLE, null, cv);

    }

我尝试使用此线程输入值

public class Datainput implements Runnable {

    int Vid;
    Context C;

    public Datainput(Context c, int vid) {
        C = c;
        Vid = vid;

    }



    public void datainsert(int vid) {



        while (x < 5000) {

        //random number generate part

                final int vid_enter = vid;
                final String date = dateGet.format(new Date());
                final String time = timeGet.format(new Date());
                final String fuel_enter = Double.toString(rem_fuel);
                final String mafr_enter = Double.toString(17);//MAFR
                final String odo_enter = Double.toString(odometre);
                final String speed_enter = Integer.toString(z);
                final String torque_enter = Integer.toString(randomData.nextInt(50));
                final String gpsX_enter = Integer.toString(0);
                final String gpsY_enter = Integer.toString(0);
                String Pid_enter = "0";

                if(x%50==0){
                    eload=randomData.nextInt(50);

                }
                final String eload_enter = Integer.toString(eload);

                String[] array2 = { "p1234", "p3456", "p6789" };


                int number = randomData.nextInt(20);

                if (number == 12) {
                    int number2 = randomData.nextInt(array2.length - 1);
                    Pid_enter = array2[number2];

                } else {

                    Pid_enter = "0";
                }

                try {
                    DB_queryClass dbq = new DB_queryClass(C);
                    dbq.open();
                    final long b = dbq.enterStatusData(vid_enter, date, time,
                            fuel_enter, mafr_enter, odo_enter, speed_enter,
                            torque_enter, eload_enter, gpsX_enter, gpsY_enter,
                            Pid_enter);

                    dbq.close();
                } catch (Exception e) {

                }

            }
            x++;
            y0 = y;
        }
    }

    @Override
    public void run() {
        datainsert(Vid);

    }

}

我在 log cat 中遇到了这些错误

11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.os.Handler.dispatchMessage(Handler.java:92)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.os.Looper.loop(Looper.java:137)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.app.ActivityThread.main(ActivityThread.java:4448)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at java.lang.reflect.Method.invokeNative(Native Method)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at java.lang.reflect.Method.invoke(Method.java:511)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at dalvik.system.NativeStart.main(Native Method)
11-03 10:09:47.783: E/System(822): Uncaught exception thrown by finalizer
11-03 10:09:47.783: E/System(822): java.lang.IllegalStateException: Don't have database lock!
11-03 10:09:47.783: E/System(822):  at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2105)
11-03 10:09:47.783: E/System(822):  at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2197)
11-03 10:09:47.783: E/System(822):  at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2193)
11-03 10:09:47.783: E/System(822):  at android.util.LruCache.trimToSize(LruCache.java:197)
11-03 10:09:47.783: E/System(822):  at android.util.LruCache.evictAll(LruCache.java:285)
11-03 10:09:47.783: E/System(822):  at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2158)
11-03 10:09:47.783: E/System(822):  at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1130)
11-03 10:09:47.783: E/System(822):  at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1920)
11-03 10:09:47.783: E/System(822):  at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:185)
11-03 10:09:47.783: E/System(822):  at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
11-03 10:09:47.783: E/System(822):  at java.lang.Thread.run(Thread.java:856)
11-03 10:09:47.783: E/SQLiteDatabase(822): close() was never explicitly called on database '/data/data/com.Helloworld.adas_saga/databases/ADAS_DB' 
11-03 10:09:47.783: E/SQLiteDatabase(822): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1949)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1011)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:990)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1055)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:800)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at com.Helloworld.adas_saga.DB_queryClass.open(DB_queryClass.java:26)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at com.Helloworld.adas_saga.Display$1$1.run(Display.java:139)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.os.Handler.handleCallback(Handler.java:605)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.os.Handler.dispatchMessage(Handler.java:92)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.os.Looper.loop(Looper.java:137)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at android.app.ActivityThread.main(ActivityThread.java:4448)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at java.lang.reflect.Method.invokeNative(Native Method)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at java.lang.reflect.Method.invoke(Method.java:511)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
11-03 10:09:47.783: E/SQLiteDatabase(822):  at dalvik.system.NativeStart.main(Native Method)
4

1 回答 1

0

尝试在您的数据库助手中声明一个可重入锁,并在您访问数据库的任何地方锁定和解锁。这应该允许线程等待数据库可用性并避免崩溃/错误。例如在数据库助手中:

public static Lock l = new ReentrantLock(false);

在您访问数据库的任何地方:

l.lock();
try
{
       //do database editing
}
finally
{
      l.unlock();
}

但是,如前所述,如果您尝试每秒写入数据库的次数超过您的数据库编辑实际上可以完成的次数,您最终会积压大量数据库写入。我的建议是每次发生数据库写入触发器时都使用时间戳比较,并跳过写入数据库,除非它已经,例如,自从您上次将该信息写入数据库以来已经过了半秒。

于 2013-11-03T08:40:42.087 回答