具有集成SQLite数据库的应用程序不断崩溃

时间:2013-08-29 19:08:34

标签: android sqlite android-sqlite

我是Android编程的新手,我正在尝试使用集成的SQLite数据库制作应用程序。

在编写将数据库从资源文件夹复制到内部存储器的代码的许多挫败尝试之后,我偶然发现了这个 SQLiteAssetHelper 库并尝试使用它,但它只是打开空白的应用程序屏幕,几秒钟后,它崩溃并显示消息“(AppName)已停止”。

我在真实设备中测试我的应用程序,一个非根的三星Galaxy S3。

一些代码:

MainActivity

package com.example.database2;

import android.os.Bundle;
import android.app.ListActivity;
import android.database.Cursor;
import android.support.v4.widget.SimpleCursorAdapter;
import android.widget.ListAdapter;


public class MainActivity extends ListActivity {

private Cursor employees;
private Database db;

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

db = new Database(this);
employees = db.getEmployees(); 

ListAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1,
employees,
new String[] {"name"},
new int[] {android.R.id.text1},0);

getListView().setAdapter(adapter);
}

@Override
protected void onDestroy() {
super.onDestroy();
employees.close();
db.close();
}


}

SQLite资产助手

package com.example.database2;

import android.content.Context;
import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;

public class Database extends SQLiteAssetHelper {

    private static final String DATABASE_NAME = "contacts.db";
    private static final int DATABASE_VERSION = 1;

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



public Cursor getEmployees() {

SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

String [] sqlSelect = {"_id", "name", "number"};
String sqlTables = "contacts.db";

qb.setTables(sqlTables);
Cursor c = qb.query(db, sqlSelect, null, null,
null, null, null);

c.moveToFirst();
return c;

}



}

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.database2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.database2.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

如果有人可以提供帮助,我很高兴。

编辑:

我发布了相关的logcat,虽然它没有给我很多信息:

logcat的

E/SQLiteDatabase(3658): Failed to open database '/data/data/com.example.database2/databases/contacts'.
E/SQLiteDatabase(3658): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
E/SQLiteDatabase(3658): at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
E/SQLiteDatabase(3658): at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:278)

2 个答案:

答案 0 :(得分:0)

哦,事实证明问题很简单而且很愚蠢:我只是将我的压缩数据库复制到assets文件夹,结果发现它应该复制到 assets / databases 中,以便SQLiteAssetHelper工作

创建文件夹并将数据库放入其中后,一切正常。

答案 1 :(得分:-1)

你可以添加LogCat输出它崩溃的原因吗?

您的数据库名称是contacts.db,而不是您的表名

请在

中设置正确的表名
String sqlTables = "your_table_name";

编辑: 我试着简要介绍在Android中使用SQLite,就像我在我的一个项目中所做的那样。

首先你有一个DBHandler类:

 public class DBHandler extends SQLiteOpenHelper {

    // table names
    public static final String TABLE_NAME = "contacts";

    // table column names
    public static final String COLUMN_ID = "id";
    public static final String COLUMN_NAME = "name";
    public static final String COLUMN_NUMBER = "number";

    // Database Name
    private static final String DATABASE_NAME = "contacts";
    private static final int DATABASE_VERSION = 1;

    // Statements for creating tables
    private static final String TABLE_CREATE = "CREATE TABLE "
            + TABLE_NAME + " (" + COLUMN_ID
            + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + COLUMN_NAME
            + " VARCHAR(255)," + COLUMN_NUMBER + " VARCHAR(255);";

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

    // Create tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLE_CREATE);
    }

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

然后你需要一个处理你的查询和其他东西的类......让我们称之为DataSource:

public class DataSource {

// Database fields
private SQLiteDatabase database;
private DBHandler databaseHelper;
private String[] allColumns = { DBHandler.COLUMN_ID,
        DBHandler.COLUMN_NAME, DBHandler.COLUMN_NUMBER};

public DataSource(Context context) {
    databaseHelper = new DBHandler(context);
        this.open();
}

public void open() throws SQLException {
    database = databaseHelper.getWritableDatabase();
}

public void close() {
    databaseHelper.close();
}

    // here you can place your custom functions 
    public Cursor getEmployees(){
            Cursor cursor = database.query(DBHandler.TABLE_NAME,
            allColumns, null, null, null, null, null);
            cursor.moveToFirst();
            return cursor;
    }
}

在您的MainActivity中,您可以:

public class MainActivity extends ListActivity {

        private Cursor employees;
        private DataSource datasource;
        private SimpleCursorAdapter adapter;

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

        datasource = new DataSource(this);
        employees = datasource.getEmployees(); 

        adapter = new SimpleCursorAdapter(this,
        android.R.layout.simple_list_item_1,
        employees,
        new String[] {"name"},
        new int[] {android.R.id.text1},0);

        this.setListAdapter(adapter);
    }

    @Override
    public void onResume() {
        datasource.open();
        super.onResume();
    }

    @Override
    public void onPause() {
        datasource.close();
        super.onPause();
    }
}

您的布局应如下所示:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" >
    <ListView
        android:id="@android:id/android:list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

重要的是ListView的id是android:list。

我没有测试这个特别的,但我调整了我的代码。它应该像那样工作。