Android自定义SQLite构建

Android自定义SQLite构建

本文介绍了Android自定义SQLite构建-无法打开数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的目标是构建一个自定义版本的SQLite(特别是启用了R-Tree的版本)以包含在我的Android项目中。动机来自于:

My goal is to build a custom version of SQLite (specifically with R-Tree enabled) to include in my Android project. The motivation stems from:

SQLite对此有一些说明:

SQLite has some instructions in how to do this:

我已经编译了SQLite并将共享库成功包含在我的项目中。我遇到的问题是,一旦调用诸如 getReadableDatabase() getWriteableDatabase()之类的操作,接收到一个SQLiteCantOpenDatabaseException。

I have compiled SQLite and successfully included the shared library in my project. The problem I am having is that as soon as I call an operation such as getReadableDatabase() or getWriteableDatabase() I receive a SQLiteCantOpenDatabaseException.

重要的是要注意我正在使用:

It is important to note that I am using:

import org.sqlite.database.sqlite.SQLiteDatabase;

import org.sqlite.database.sqlite.SQLiteOpenHelper;

代替:

导入android。 database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

为了通过NDK和JNI使用自定义SQLite构建。

In order to use the custom SQLite build through the NDK and JNI.

MySQLiteHelper:

MySQLiteHelper:

public class MySQLiteHelper extends SQLiteOpenHelper {

    static {
        System.loadLibrary("sqliteX");
    }

    private static final String DATABASE_NAME = "mydata.db";
    private static final int DATABASE_VERSION = 1;
    Context myContext;

    public MySQLiteHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        myContext = context;
    }

    public void getEntry(){
        SQLiteDatabase db = this.getReadableDatabase();
        db.close();
    }

    public void createEntry(){
        // 1. get reference to writable DB
        SQLiteDatabase db = this.getWritableDatabase();
        //...
        //...
        db.close();
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
         String create_rtree = "CREATE VIRTUAL TABLE demo_index USING rtree(\n" +
                "   id,              -- Integer primary key\n" +
                "   minX, maxX,      -- Minimum and maximum X coordinate\n" +
                "   minY, maxY       -- Minimum and maximum Y coordinate\n" +
                ");";

        database.execSQL(create_rtree);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(MySQLiteHelper.class.getName(),
            "Upgrading database from version " + oldVersion + " to "
                    + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS " + "demo_index");
        onCreate(db);
    }

}

主要活动:

Main Activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    MySQLiteHelper helper = new MySQLiteHelper(this);
    helper.createEntry();
    setContentView(R.layout.activity_my);
}

堆栈跟踪:

Stack Trace:

10-29 13:45:38.356    2360-2360/com.example.nathanielwendt.lstrtree E/SQLiteLog﹕ (14)   os_unix.c:30589: (2) open(//arrrr.db) -
10-29 13:45:38.376    2360-2360/com.example.nathanielwendt.lstrtree E/SQLiteDatabase﹕ Failed to open database 'arrrr.db'.
    org.sqlite.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
        at org.sqlite.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
        at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:217)
        at org.sqlite.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:201)
        at     org.sqlite.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:467)
        at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:189)
        at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:181)
        at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:809)
        at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:794)
        at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:699)
        at org.sqlite.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:722)
        at org.sqlite.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:228)
        at org.sqlite.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:168)
        at com.example.nathanielwendt.lstrtree.MySQLiteHelper.createEntry(MySQLiteHelper.java:65)
        at com.example.nathanielwendt.lstrtree.MyActivity.onCreate(MyActivity.java:25)

我在SO上看到过几篇关于此的文章例外,但它们似乎都与从磁盘上其他位置(未正确设置文件路径)的导入有关。这似乎是最相关的帖子:,但是所有建议都没有。

I have seen several posts here on SO about this same exception, but they all seem to be related to importing the database from somewhere else on disk in which they do not set the file path correctly. This seems to be the most related post: Android SQLiteOpenHelper cannot open database file, but none of the suggestions worked.

我已经用2部不同的手机和模拟器尝试了此操作,但收到了相同的错误。此外,我已经用默认的android sqlite导入替换了上面讨论的导​​入,并且可以正常工作(假设我不尝试创建R-Tree,因为默认Android SQLite安装中未包含R-Tree)。将数据库dir和.db文件的权限更改为777不能解决问题,也没有在我的清单中添加WRITE_PERMISSION。

I have tried this with 2 different phones and with the emulator and I receive the same error. Furthermore, I have replaced the imports discussed above with the default android sqlite imports and it works fine (given I don't try to create an R-Tree since it is not included in the default Android SQLite install). Changing permissions of database dir and .db file to 777 did not fix the issue, neither did adding WRITE_PERMISSION to my manifest.

推荐答案

这是SQLite Android绑定中的不兼容。

This is an incompatibility in the SQLite Android bindings.

原始的Android代码像这样打开数据库:

The original Android code opens the database like this:

db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
        Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
        mFactory, mErrorHandler);

org.sqlite.database.sqlite.SQLiteOpenHelper 不使用上下文:

db = SQLiteDatabase.openOrCreateDatabase(
        mName, mFactory, mErrorHandler
);

这意味着数据库路径不位于数据库名称的前面。

This means that the database path is not prepended to the database name.

使用类似的方法获取数据库的完整路径:

Use something like this to get the complete path of the database:

String path = context.getDatabasePath(DATABASE_NAME).getPath();

并将其用作数据库名称。

and use that as the database name.

这篇关于Android自定义SQLite构建-无法打开数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 18:29