首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在android中使用线程访问sqlite

如何在android中使用线程访问sqlite
EN

Stack Overflow用户
提问于 2013-11-03 12:50:45
回答 1查看 176关注 0票数 0

我有随机数生成器。我需要输入随机数到sqlite数据库中使用线程.I写了这段代码,但几次后它会关闭应用程序。我是新手安卓我对此感到困惑,我必须在未来两天内完成这一点,请帮助我这是我的第一次sqlite经验(我删除了一些代码部分,因为超过字符限制,并为发布整个代码,因为我正在识别错误的部分)

我的数据库类

代码语言:javascript
复制
   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;

    } 

我在单独的类中编写查询

代码语言:javascript
复制
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);

    }

我试着用这个线程输入值

代码语言:javascript
复制
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中得到了这些错误

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

发布于 2013-11-03 16:40:42

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

代码语言:javascript
复制
public static Lock l = new ReentrantLock(false);

无论您在何处访问数据库:

代码语言:javascript
复制
l.lock();
try
{
       //do database editing
}
finally
{
      l.unlock();
}

但是,如前所述,如果您尝试每秒写入数据库的次数超过数据库编辑实际完成的次数,则会导致数据库写入操作积压很长时间。我的建议是每次触发数据库写入时使用时间戳比较,并跳过写入数据库,除非距离上次写入数据库已经过去了半秒。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19749937

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档