1

我正在尝试从我的国家数据库中选择一个国家并将其返回到光标以显示在 TextView 中。但是,每次我运行此活动时,我的应用程序都会崩溃。这是我的代码:

数据库类:

package com.mypackage.msdassignment;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;

public class DBManager 
{
    public static final String KEY_ID = "_id";
    public static final String KEY_CONTENT = "country";
    public static final String KEY_YEAR = "year";
    public static final String KEY_MONTH = "month";
    public static final String KEY_DESC = "description";

    public static final String DATABASE_NAME = "Countries database";
    public static final String DATABASE_TABLE = "Country";
    public static final int DATABASE_VERSION = 1;

    //create table MY_DATABASE (ID integer primary key, Content text not null);
    private static final String SCRIPT_CREATE_DATABASE =
            "create table " + DATABASE_TABLE + " ("
            + KEY_ID + " integer primary key autoincrement, "
            + KEY_CONTENT + " text ,"
            + KEY_YEAR + " integer ,"
            + KEY_MONTH + " month ,"
            + KEY_DESC + " text);";

    private Context context;
    private DBHelper DBHelper;
    private SQLiteDatabase db;

    public DBManager(Context ctx)
    {
        context = ctx;
    }

    //beginning of helper class
    public class DBHelper extends SQLiteOpenHelper 
    {
        public DBHelper(Context context, String name, CursorFactory factory, int version) 
        {
            super(context, name, factory, version);
        }

        @Override
        public void onCreate(SQLiteDatabase db)
        {
             db.execSQL(SCRIPT_CREATE_DATABASE);
        }

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

    public DBManager openToRead() throws SQLException 
    {
        DBHelper = new DBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
        db = DBHelper.getReadableDatabase();
        return this;
    }

    public DBManager openToWrite() throws SQLException 
    {
        DBHelper = new DBHelper(context, DATABASE_NAME, null, DATABASE_VERSION);
        db = DBHelper.getWritableDatabase();
        return this;
    }

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

    public long insert(String content, int year, String month, String description)
    {
        ContentValues contentValues = new ContentValues();
        contentValues.put(KEY_CONTENT, content);
        contentValues.put(KEY_YEAR, year);
        contentValues.put(KEY_MONTH, month);
        contentValues.put(KEY_DESC, description);
        return db.insert(DATABASE_TABLE, null, contentValues);
    }

    public int deleteAll()
    {
        return db.delete(DATABASE_TABLE, null, null);
    }

    public void deleteDatabase()
    {
        context.deleteDatabase(DATABASE_NAME);
    }

    public Cursor queueAll()
    {
        String[] columns = new String[]{
                KEY_ID, 
                KEY_CONTENT,
                KEY_YEAR,
                KEY_MONTH,
                KEY_DESC};
        Cursor cursor = db.query(DATABASE_TABLE, columns,
          null, null, null, null, null);

        return cursor;
    }

    //this is the method with the problem
    public Cursor getCountry()
    {
        Cursor cursor = db.query(DATABASE_TABLE, new String[] {"country", "month"}, 
                "country like " + "'%Ireland%'", null, null, null, null);

        return cursor;
    }
}

我试图获得国家的活动:

package com.mypackage.msdassignment;

import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class CountryInfo extends Activity
{
    private DBManager db;
    Cursor cursor;
    String passedValue;
    TextView mytextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.country_layout);

        //intent passed data
        passedValue = getIntent().getStringExtra(MainActivity.ID_EXTRA);
        int num = Integer.parseInt(passedValue);
        mytextView = (TextView)findViewById(R.id.country);

        db = new DBManager(this);
        db.openToRead();

        cursor = db.getCountry();
        String s = cursor.getString(1);
        mytextView.setText(s);
    }
}

Logcat 错误:

04-02 22:29:30.980: D/AndroidRuntime(17632): procName from cmdline: com.mypackage.msdassignment
04-02 22:29:30.980: E/AndroidRuntime(17632): in writeCrashedAppName, pkgName :com.mypackage.msdassignment
04-02 22:29:30.980: D/AndroidRuntime(17632): file written successfully with content: com.mypackage.msdassignment StringBuffer : ;com.mypackage.msdassignment
04-02 22:29:30.980: E/AndroidRuntime(17632): FATAL EXCEPTION: main
04-02 22:29:30.980: E/AndroidRuntime(17632): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mypackage.msdassignment/com.mypackage.msdassignment.CountryInfo}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.os.Looper.loop(Looper.java:130)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.app.ActivityThread.main(ActivityThread.java:3683)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at java.lang.reflect.Method.invokeNative(Native Method)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at java.lang.reflect.Method.invoke(Method.java:507)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:638)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at dalvik.system.NativeStart.main(Native Method)
04-02 22:29:30.980: E/AndroidRuntime(17632): Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at com.mypackage.msdassignment.CountryInfo.onCreate(CountryInfo.java:31)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
04-02 22:29:30.980: E/AndroidRuntime(17632):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
04-02 22:29:30.980: E/AndroidRuntime(17632):    ... 11 more
04-02 22:29:31.330: W/ResourceType(17644): Skipping entry 0x7f060002 in package table 0 because it is not complex!
04-02 22:29:31.330: W/ResourceType(17644): Skipping entry 0x7f060002 in package table 0 because it is not complex!
04-02 22:29:31.330: W/ResourceType(17644): Skipping entry 0x7f060002 in package table 0 because it is not complex!
04-02 22:29:31.330: W/ResourceType(17644): Skipping entry 0x7f060002 in package table 0 because it is not complex!
04-02 22:29:31.330: W/ResourceType(17644): Skipping entry 0x7f060002 in package table 0 because it is not complex!
4

3 回答 3

2

我似乎无法.moveToFirst()在您的光标上找到方法调用,它将光标移动到结果集的第一行。我相信这很可能是您的问题的原因。

所以,尝试类似的东西

cursor = db.getCountry();

if(cursor.moveToFirst()) {
    String s = cursor.getString(1); 
    mytextView.setText(s);
}

另外,请记住 getString 方法是从零开始的(正如其他人在他们的答案中所指出的那样)。使用 1 将为您提供“月份”列,由于您的文本字段 ID 的名称,我怀疑这不是您要查找的内容:)

于 2013-04-02T22:43:13.040 回答
1

引起:android.database.CursorIndexOutOfBoundsException:请求索引-1,大小为1

没有问题。moveToFirst()只是您忘记在光标上调用方法。

解释:

每个Cursor总是隐式定位在第一行之前。这就是您的应用程序崩溃的原因。您试图从 -1 行中获取实际上不存在的值。解决方案是调用此方法,将光标移动到第一行并准备好读取。

if (c.moveToFirst()) {
   // do your stuff
}

建议:

如果要从中获取值Cursor,请始终使用c.getColumnIndex("columnName")方法来避免“错字”和“编号”错误。

于 2013-04-02T22:46:37.707 回答
0

您可能是指 getString(0),也可能想调用 moveToFirst()。

于 2013-04-02T22:45:00.420 回答