【问题标题】:Android app crashes when trying to connect to SQLite database尝试连接到 SQLite 数据库时,Android 应用程序崩溃
【发布时间】:2017-12-23 19:08:07
【问题描述】:

我的 android 应用程序崩溃并显示此错误。

package com.example.sanket.databaseexample;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.StrictMode;

/**
 * Created by sanket on 18-07-2017.
 */

public class DBHandler extends SQLiteOpenHelper{
    private static  final int DATABASE_VERSION =1;
    private static final String DATABASE_NAME = "products.db";
    public static final String TABLE_PRODUCTS = "products";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_PRODUCTNAME = "product_name";

    public DBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String query ="CREATE TABLE " + TABLE_PRODUCTS + "("  +
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT ,"+
                COLUMN_PRODUCTNAME + " TEXT "+
                ")";
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            db.execSQL("DROP  TABLE IF EXISTS " + TABLE_PRODUCTS );
            onCreate(db);
    }
    public void addProduct(Products product){
        ContentValues values = new ContentValues();
        values.put(COLUMN_PRODUCTNAME,product.getProduct_name());
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_PRODUCTS,null,values);
        db.close();
    }
    public void deleteProduct(String prductName){
        SQLiteDatabase db = getWritableDatabase();
        db.execSQL("DELETE FROM " + TABLE_PRODUCTS + " WHERE " + COLUMN_PRODUCTNAME+ " =\"" + prductName + "\";");
    }
    public String databaseToString(){
        String dbString = "";
        SQLiteDatabase db = getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_PRODUCTS +" WHERE 1";
        Cursor c = db.rawQuery(query,null);
        if(c.getCount() > 0) {
            c.moveToFirst();
            while (!c.isAfterLast()) {
                if (c.getString(c.getColumnIndex("productname")) != null) {
                    dbString += c.getString(c.getColumnIndex("productname"));
                    dbString += "\n";
                }
            }
        }
        db.close();
        return dbString;
    }
}

日志:

07-19 00:13:34.764 18415-18415/?我/艺术:不延迟启用 -Xcheck:jni (已经开启)07-19 00:13:34.765 18415-18415/? W/art:意外的 CPU 使用默认值的 X86 变体:x86 07-19 00:13:35.243 18415-18415/com.example.sanket.databaseexample W/系统:类加载器 引用的未知路径: /data/app/com.example.sanket.databaseexample-2/lib/x86 07-19 00:13:35.501 18415-18422/com.example.sanket.databaseexample W/艺术: 暂停所有线程耗时:7.283ms 07-19 00:13:35.506 18415-18415/com.example.sanket.databaseexample W/art:在 Android 之前 4.1、方法android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) 会错误地覆盖 package-private 方法 android.graphics.drawable.Drawable 07-19 00:13:35.992 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:7.732ms 07-19 00:13:36.142 18415-18415/com.example.sanket.databaseexample E/CursorWindow:失败 从具有 1 行 2 的 CursorWindow 读取第 0 行第 -1 列 列。 07-19 00:13:36.143 18415-18415/com.example.sanket.databaseexample D/AndroidRuntime: 关闭虚拟机

--------- 崩溃开始 07-19 00:13:36.148 18415-18415/com.example.sanket.databaseexample E/AndroidRuntime: FATAL 例外:主要 进程:com.example.sanket.databaseexample,PID:18415 java.lang.RuntimeException:无法启动活动 组件信息{com.example.sanket.databaseexample/com.example.sanket.databaseexample.MainActivity}: java.lang.IllegalStateException:无法读取第 0 行,列 -1 光标窗口。确保光标在之前正确初始化 从中访问数据。 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 在 android.app.ActivityThread.-wrap12(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6077) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 引起:java.lang.IllegalStateException:无法读取第 0 行,col -1 来自光标窗口。确保在从光标访问数据之前正确初始化光标。 在 android.database.CursorWindow.nativeGetString(Native Method) 在 android.database.CursorWindow.getString(CursorWindow.java:438) 在 android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:51) 在 com.example.sanket.databaseexample.DBHandler.databaseToString(DBHandler.java:57) 在 com.example.sanket.databaseexample.MainActivity.printDatabase(MainActivity.java:37) 在 com.example.sanket.databaseexample.MainActivity.onCreate(MainActivity.java:24) 在 android.app.Activity.performCreate(Activity.java:6662) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 在 android.app.ActivityThread.-wrap12(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6077) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) 07-19 00:13:42.576 18415-18422/com.example.sanket.databaseexample W/艺术: 暂停所有线程花费:16.982ms 07-19 00:13:45.084 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:16.342ms 07-19 00:13:46.553 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:5.273ms 07-19 00:13:49.082 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:14.783ms 07-19 00:13:55.105 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:17.910ms 07-19 00:13:55.594 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:5.317ms 07-19 00:14:04.126 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:6.876ms 07-19 00:14:05.626 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:6.402ms 07-19 00:14:07.622 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程占用:5.339ms 07-19 00:14:16.655 18415-18422/com.example.sanket.databaseexample W/art:暂停所有 线程耗时:6.749ms

【问题讨论】:

    标签: java android sqlite


    【解决方案1】:

    看看这个错误信息:

    无法从具有 1 行 2 列的 CursorWindow 读取第 0 行第 -1 列。

    第-1列...这怎么可能?原因是这样的:

    if (c.getString(c.getColumnIndex("productname")) != null) {
    

    表中没有名为“productname”的列。 有一个名为“product_name”。 当请求列名不存在时, getColumnIndex 方法返回 -1。

    您在创建表时使用了此常量:

    public static final String COLUMN_PRODUCTNAME = "product_name";
    

    最好将表格元素名称放在常量中, 你应该在任何地方始终如一地使用它们, 正是为了避免这种错别字, 并使维护更容易。

    if (c.getString(c.getColumnIndex(COLUMN_PRODUCTNAME)) != null) {
    

    【讨论】:

      猜你喜欢
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      • 2012-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多