0

私は乱数ジェネレーターを持っています.スレッドを使用してその乱数をsqliteデータベースに入力する必要があります.私はこのコードを書きましたが、数回後にアプリを閉じます.私はアンドロイドに慣れていませんこれは次の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 に答える