java SQLiteOpenHelper.getWritableDatabase 问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5229029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 10:05:22  来源:igfitidea点击:

SQLiteOpenHelper.getWritableDatabase problem

javaandroidsqlite

提问by prolink007

EDIT: I believe i may have found the problem. I need to work on my SmartDBHelper class. Will do this and post the results here.

编辑:我相信我可能已经发现了问题。我需要处理我的 SmartDBHelper 类。将执行此操作并在此处发布结果。

EDIT: Found a link to someone who is having similar problem. Will be checking this to see if it fixes asap. Another Post

编辑:找到指向遇到类似问题的人的链接。将检查此问题以查看它是否会尽快修复。另一个帖子

EDIT: Updated to reflect some changes made suggested by some of the posters. Problem is still occurring.

编辑:更新以反映一些海报提出的一些更改。问题仍在发生。

THE POST BELOW:

下面的帖子:

My application need to be able to write to the sqlite3 database that is on the android from 2 different events. One of my events is writing to the database just fine. When the second event tries to write to the database the attached error occurs. I have no clue why this is happening or how to fix it. I have tried numerous things the past couple hours and googled a ton. Can someone please view the code i have below and let me know what you think?

我的应用程序需要能够从 2 个不同的事件写入 android 上的 sqlite3 数据库。我的事件之一是写入数据库就好了。当第二个事件尝试写入数据库时​​,会发生附加错误。我不知道为什么会发生这种情况或如何解决它。在过去的几个小时里,我尝试了很多东西,并在谷歌上搜索了很多东西。有人可以查看我下面的代码并告诉我您的想法吗?

If you need any more information please let me know asap.

如果您需要更多信息,请尽快告诉我。

Thanks in advance!

提前致谢!

//This is the sqliteopenhelper i created
public class SmartDBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "smart_lite_db.db";
    private static final int DATABASE_VERSION = 2;
    private static final String NOTIFY_TABLE_NAME = "user_notify_data";
    private static final String HR_TABLE_NAME = "user_hr_data";
    private static final String NOTIFY_TABLE_CREATE = 
        "CREATE TABLE " + NOTIFY_TABLE_NAME + 
        " (counter INTEGER PRIMARY KEY, " + 
        "userresponse INTEGER, " + 
        "notifytime INTEGER);";
    private static final String DATA_TABLE_CREATE = 
        "CREATE TABLE " + HR_TABLE_NAME +
        " (counter INTEGER PRIMARY KEY, " +
        "hr INTEGER, " +
        "act INTEGER, " +
        "timestamp INTEGER);";      

    public SmartDBHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        Log.v("smartdbhelper", "before creation");
        db.execSQL(NOTIFY_TABLE_CREATE);
        Log.v("smartdbhelper", "middle creation");
        db.execSQL(DATA_TABLE_CREATE);
        Log.v("smartdbhelper", "after creation");
    }

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

    }

}  


//This is the part that is working CORRECTLY
public class DataNotificationSurvey extends Activity {
    private SmartDBHelper dBHelper;
    private Date timeStamp;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.datanotificationlayout);
        Log.v("datanotificationsurvey", "inside datanotificationsurvey");

            dBHelper = new SmartDBHelper(this);
        timeStamp = new Date(DataNotification.when);
        // XML code stuff left out here, was not needed


    }

    public void submitNotify(int tempType, Date tempDate) {
        SQLiteDatabase dBH = dBHelper.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put("userresponse", tempType);
        values.put("notifytime", (tempDate.getTime()/1000));
        dBH.insert("user_notify_data", null, values);
        dBH.close();
    }
}  


// This is the event that is NOT working correctly
public class DataBuilder extends Activity {
    private List _listeners = new ArrayList();
    private SmartDataObject data;
    Context tThis;
    private SmartDBHelper dBHelper;
    private Date timeStampReference; //for keeping track of the first time

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v("databuilder", "on create");
    dBHelper = new SmartDBHelper(this);
}

    public void prepareData(SmartDataObject temp) {
        submitData(temp);
    }

    public void submitData(SmartDataObject temp) {
        data = temp;
        System.out.println("Where: DB-submitData");
        try {
        SQLiteDatabase dBH = dBHelper.getWritableDatabase(); // CODE FAILS AT THIS POINT
        Log.v("databuilder", "after writable");
        ContentValues values = new ContentValues();
        values.put("hr", data.getHeartRate());
        values.put("act", data.getAct());
        values.put("timestamp", data.getTimeStamp());
        dBH.insert("user_hr_data", null, values);
        Log.v("databuilder", "after insert");
        dBH.close();
        fireDataBuilderEvent(data);
        }
        catch(SQLException e) {
            e.printStackTrace();
        }
        catch(NullPointerException e) {
            e.printStackTrace();
        }
    }
    public synchronized void addDataBuilderListener(DataBuilderListener listener) {
        _listeners.add(listener);
    }
    public synchronized void removeDataBuilderListener(DataBuilderListener listener) {
        _listeners.remove(listener);
    }
    private synchronized void fireDataBuilderEvent(SmartDataObject temp) {
        DataBuilderEvent dRE = new DataBuilderEvent(this, temp);
        Iterator listeners = _listeners.iterator();
        while(listeners.hasNext()) {
            ((DataBuilderListener)listeners.next()).dataBuilderReceived(dRE);
        }
    }
    public interface DataBuilderListener {
        public void dataBuilderReceived(DataBuilderEvent event);
    }
}   


// The error that is occuring.
03-13 17:38:40.130: INFO/System.out(279): Where: DB-submitData
03-13 17:38:40.130: WARN/System.err(279): java.lang.NullPointerException
03-13 17:38:40.151: WARN/System.err(279):     at cpe495.smartapp.DataBuilder.submitData(DataBuilder.java:41)
03-13 17:38:40.151: WARN/System.err(279):     at cpe495.smartapp.DataBuilder.prepareData(DataBuilder.java:34)
03-13 17:38:40.171: WARN/System.err(279):     at cpe495.smartapp.SmartApp.dataAnalyzedReceived(SmartApp.java:56)
03-13 17:38:40.171: WARN/System.err(279):     at cpe495.smartapp.DataRobot.fireDataAnalyzedEvent(DataRobot.java:269)
03-13 17:38:40.181: WARN/System.err(279):     at cpe495.smartapp.DataRobot.analyzeData(DataRobot.java:79)
03-13 17:38:40.181: WARN/System.err(279):     at cpe495.smartapp.SmartApp.dataReceivedReceived(SmartApp.java:49)
03-13 17:38:40.191: WARN/System.err(279):     at cpe495.smartapp.ConnectDevice.fireDataReceivedEvent(ConnectDevice.java:79)
03-13 17:38:40.201: WARN/System.err(279):     at cpe495.smartapp.ConnectDevice.run(ConnectDevice.java:46)
03-13 17:38:40.211: WARN/System.err(279):     at java.lang.Thread.run(Thread.java:1096)

采纳答案by colig

A quick guess: change private SmartDBHelper dBHelper = new SmartDBHelper(this);to just private SmartDBHelper dBHelper;and only initialize the new object in onCreate().

快速猜测:更改private SmartDBHelper dBHelper = new SmartDBHelper(this);为仅private SmartDBHelper dBHelper;在 onCreate() 中初始化新对象。

回答by G_V

I had this problem and while I wouldn't normally tell anyone to purposely leak anything, this was the only stable quick fix I could think of.

我遇到了这个问题,虽然我通常不会告诉任何人故意泄漏任何东西,但这是我能想到的唯一稳定的快速修复方法。

This fixed it for me;

这为我修复了它;

private static YourSQLiteOpenHelper helperAnchor;

private static YourSQLiteOpenHelper helperAnchor;

And in onCreate

并在 onCreate

helperAnchor = this;

helperAnchor = this;

So basically give the object a reference to itself to keep it alive because in my case there was nowhere else to sensibly put it due to calling my local db from a large number of classes in a ViewPager. This comes with the added downside of having to create another method to set it to null again, which you have to call wherever you want to clean it up.

所以基本上给对象一个对自身的引用以使其保持活动状态,因为在我的情况下,由于从 ViewPager 中的大量类调用我的本地数据库,没有其他地方可以明智地放置它。这带来了必须创建另一个方法来再次将其设置为 null 的额外缺点,您必须在任何想要清理它的地方调用它。

But hey, it just werks. The application is super stable now where before it would crash on the SQLiteOpenHelper being null at random times. Please tell me if/when there's a better way to do it because quite frankly I don't like using this either.

但是,嘿,它只是起作用。该应用程序现在非常稳定,之前它会在 SQLiteOpenHelper 随机为空时崩溃。请告诉我是否/何时有更好的方法来做到这一点,因为坦率地说,我也不喜欢使用它。

回答by XCH

use SQLiteDatabase's methods to check the database status

使用 SQLiteDatabase 的方法检查数据库状态

isDbLockedByCurrentThread()
isDbLockedByOtherThreads

isDbLockedByCurrentThread()
isDbLockedByOtherThreads

I think it's lock by another thread. Or check your provider setting in Androidmanifest.xml.

我认为它被另一个线程锁定。或者在 Androidmanifest.xml 中检查您的提供程序设置。