无法从sqlite数据库索引中获取一行注释超出范围

时间:2013-11-14 17:47:46

标签: android sqlite

我试图将帐户活动设置为onItemClick的结果,并将帐户信息存储在SQLite数据库中,我希望根据列表视图中单击的相应帐户名称显示该数据库。但是,当我尝试从数据库中选择一行时,迭代它,并将其作为ArrayList返回我得到一个错误我认为很多说没有创建Arraylist。我似乎无法找到问题所在。

这是数据访问对象类,我在其中创建了getRow()方法,我相信这就是问题所在。

`package com.example.hardwoodassistant;

import java.util.ArrayList;
import java.util.List;

import com.example.hardwoodassistant.Comment;
import com.example.hardwoodassistant.MySQLiteHelper;

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

public class CommentsDataSource {

// Database fields
  private static SQLiteDatabase database;
  private MySQLiteHelper db;
  private String[] allColumns = { MySQLiteHelper.COLUMN_ID,
      MySQLiteHelper.KEY_NAME, MySQLiteHelper.KEY_STREET, MySQLiteHelper.KEY_CITY,  
      MySQLiteHelper.KEY_PHONE, MySQLiteHelper.KEY_EMAIL};

  public  CommentsDataSource(Context ctx) {
      db = MySQLiteHelper.getInstance(ctx);
  }

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

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

  public Comment createComment(String name, String _name, String street, String _street, String city, String _city,
          String phone, String _phone, String email, String _email) {
    ContentValues values = new ContentValues();
    values.put(name, _name);
    values.put(street, _street);
    values.put(city, _city);
    values.put(phone, _phone);
    values.put(email, _email);

    long insertId = database.insert(MySQLiteHelper.TABLE_COMMENTS, null,
        values);
    Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, new String[] {MySQLiteHelper.COLUMN_ID, name},
        MySQLiteHelper.COLUMN_ID + " = " + insertId, null,
        null, null, null, null);
    cursor.moveToFirst();
    Comment newComment = cursorToComment(cursor);
    cursor.close();
    return newComment;
  }

  public void deleteComment(Comment comment) {
    long id = comment.getId();
    System.out.println("Comment deleted with id: " + id);
    database.delete(MySQLiteHelper.TABLE_COMMENTS, MySQLiteHelper.COLUMN_ID
        + " = " + id, null);
  }

  public List<Comment> getAllComments() {
        List<Comment> comments = new ArrayList<Comment>();

        Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS,
            allColumns, null, null, null, null, null);

        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
          Comment comment = cursorToComment(cursor);
          comments.add(comment);
          cursor.moveToNext();
        }
        // make sure to close the cursor
        cursor.close();
        return comments;
      }

  public List<Comment> getNames()   {
      List<Comment> names = new ArrayList<Comment>();
      Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, new String[] {MySQLiteHelper.COLUMN_ID, MySQLiteHelper.KEY_NAME}, 
              null, null, null, null, null);
      cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
          Comment comment = cursorToComment(cursor);
          names.add(comment);
          cursor.moveToNext();
        }

      cursor.close();
      return names;
  }

  public List<Comment> getRow(int id)   {
      List<Comment> row = new ArrayList<Comment>();
      Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, new String[] {MySQLiteHelper.COLUMN_ID, 
              MySQLiteHelper.KEY_NAME, MySQLiteHelper.KEY_STREET, MySQLiteHelper.KEY_CITY, MySQLiteHelper.KEY_PHONE, 
              MySQLiteHelper.KEY_EMAIL}, MySQLiteHelper.COLUMN_ID + " =" + (id-1),null,null,null, null );

      while (cursor.moveToNext()) {
          Comment comment = cursorToComment(cursor);
          row.add(comment);
      }

      cursor.close();

      return row;
      }




  private Comment cursorToComment(Cursor cursor) {
        Comment comment = new Comment();
        comment.setId(cursor.getLong(0));
        comment.setComment(cursor.getString(1));
        return comment;
        }
}`

这是显示个人帐户信息的帐户活动。

package com.example.hardwoodassistant;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class Customer_account extends Activity {
private CommentsDataSource datasource;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.customer_details);

    datasource = new CommentsDataSource(this);
    datasource.open();

    TextView name = (TextView) findViewById(R.id.textView1);
    TextView address = (TextView) findViewById(R.id.textView2);
    TextView phone = (TextView) findViewById(R.id.textView3);
    TextView email = (TextView) findViewById(R.id.textView4);

    int position = getIntent().getExtras().getInt("position");

    name.setText(datasource.getRow(position).get(0).toString());
    address.setText(datasource.getRow(position).get(1).toString() + " " + datasource.getRow(position).get(2).toString());
    phone.setText(datasource.getRow(position).get(3).toString());
    email.setText(datasource.getRow(position).get(4).toString());

    }

}

这是显示onitemclick帐户的listactivity。

package com.example.hardwoodassistant;

import java.util.List;


import com.example.hardwoodassistant.Comment;
import com.example.hardwoodassistant.R;


import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class Customer_Home extends ListActivity {
private CommentsDataSource datasource;

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.customer_home);

    ListView lv = getListView();

    datasource = new CommentsDataSource(this);
    datasource.open();

    List<Comment> names = datasource.getNames();

    ArrayAdapter<Comment> adapter = new ArrayAdapter<Comment>(this,
            android.R.layout.simple_list_item_1, names);

    setListAdapter(adapter);

}

public void onClick(View view) {
    switch(view.getId())    {
        case R.id.add: 
            Intent toBidInfo = new Intent(Customer_Home.this, Bid_customerinfo.class);
            toBidInfo.putExtra("isFromAccounts", true);
            startActivity(toBidInfo);

    }
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    // TODO Auto-generated method stub
    super.onListItemClick(l, v, position, id);

    Intent intent = new Intent(Customer_Home.this, Customer_account.class);
    intent.putExtra("position", position);

    startActivity(intent);
}

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

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

  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.home, menu);
        return true;
    }

}

这里是logcat

    11-14 10:41:57.136: E/AndroidRuntime(9457):     at        android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2246)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2296)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.app.ActivityThread.access$700(ActivityThread.java:151)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1281)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.os.Looper.loop(Looper.java:137)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.app.ActivityThread.main(ActivityThread.java:5293)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at java.lang.reflect.Method.invokeNative(Native Method)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at java.lang.reflect.Method.invoke(Method.java:511)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at dalvik.system.NativeStart.main(Native Method)
11-14 10:41:57.136: E/AndroidRuntime(9457): Caused by: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
11-14 10:41:57.136: E/AndroidRuntime(9457):     at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at java.util.ArrayList.get(ArrayList.java:304)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at com.example.hardwoodassistant.Customer_account.onCreate(Customer_account.java:26)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.app.Activity.performCreate(Activity.java:5250)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1097)
11-14 10:41:57.136: E/AndroidRuntime(9457):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2210)

编辑:抱歉,还有其他一些活动,我试图保持简短,但这是我为数据库创建评论的活动。

package com.example.hardwoodassistant;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.TextView;

public class Bid_verify extends Activity {
private CommentsDataSource datasource;
//boolean isFromAccounts = getIntent().getExtras().getBoolean("isFromAccounts");

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.bid_verify);

    datasource = new CommentsDataSource(this);
    datasource.open();

    final ArrayList<Account> accounts = new ArrayList<Account>();

    TextView name = (TextView) findViewById(R.id.textView1);
    TextView street = (TextView) findViewById(R.id.TextView01);
    TextView city = (TextView) findViewById(R.id.TextView02);
    TextView phone = (TextView) findViewById(R.id.TextView04);
    TextView email = (TextView) findViewById(R.id.TextView03);

    name.setText(getIntent().getExtras().getString("name"));
    street.setText(getIntent().getExtras().getString("street"));
    city.setText(getIntent().getExtras().getString("city"));
    phone.setText(getIntent().getExtras().getString("phone"));
    email.setText(getIntent().getExtras().getString("email"));

    System.out.println(name.getText());

    Button next = (Button) findViewById(R.id.button5);


    next.setOnClickListener(new OnClickListener() {


            @Override
            public void onClick(View v) {
                //if (isFromAccounts)   {

                Comment comment = null;

                accounts.add(new Account(getIntent().getExtras().getString("name"),
                        getIntent().getExtras().getString("street"), 
                        getIntent().getExtras().getString("city"), 
                        getIntent().getExtras().getString("phone"),
                        getIntent().getExtras().getString("email")));
                System.out.println(accounts.size());

                datasource.createComment("name", getIntent().
                        getExtras().getString("name"), "street", getIntent().
                        getExtras().getString("street"), "city", getIntent().
                        getExtras().getString("city"), "phone", getIntent().
                        getExtras().getString("phone"), "email", getIntent().
                        getExtras().getString("email"));



                Intent toAccounts = new Intent(Bid_verify.this, Customer_account.class);
                startActivity(toAccounts);
                }

                //else  {
                      //startActivity(new Intent(Bid_verify.this, Bid_jobtype.class));
                    //}
            });

        }       

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

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

}

SQLiteHelper类

package com.example.hardwoodassistant;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;


public final class MySQLiteHelper extends SQLiteOpenHelper {

private static MySQLiteHelper sInstance = null;

public static final String TABLE_COMMENTS = "comments";
public static final String COLUMN_ID = "_id";
public static final String KEY_NAME = "name";
public static final String KEY_STREET = "street";
public static final String KEY_CITY = "city";
public static final String KEY_PHONE = "phone";
public static final String KEY_EMAIL = "email";

public static final String COLUMN_COMMENT = "comment";

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

private static final String DATABASE_CREATE = "create table "
          + TABLE_COMMENTS + "(" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_NAME
          + " TEXT," + KEY_STREET + " TEXT," + KEY_CITY + " TEXT," + KEY_PHONE + " TEXT," 
          + KEY_EMAIL + " TEXT" + ")";



private MySQLiteHelper(Context ctx) {
    super(ctx, DATABASE_NAME, null, DATABASE_VERSION);

}

public static MySQLiteHelper getInstance(Context ctx) {
    if(sInstance == null)   {
        sInstance = new MySQLiteHelper(ctx.getApplicationContext());
    }
        return sInstance;

}

public static String getName()  {
    return DATABASE_NAME;
}

@Override
  public void onCreate(SQLiteDatabase database) {
    if(database == null);
    database.execSQL(DATABASE_CREATE);
}

@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 " + TABLE_COMMENTS);
    onCreate(db);
}

}

2 个答案:

答案 0 :(得分:0)

我的第一个答案并不是很有帮助。所以我再试一次。我认为问题来自这一行:

name.setText(datasource.getRow(position).get(0).toString());

这表明您遇到的问题(IndexOutOfBound因为您的列表为空)是因为方法getRow(position)返回一个空列表。

当我看到这一行时,我会说你查询一个不存在的行。

 Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, new String[] {MySQLiteHelper.COLUMN_ID, 
              MySQLiteHelper.KEY_NAME, MySQLiteHelper.KEY_STREET, MySQLiteHelper.KEY_CITY, MySQLiteHelper.KEY_PHONE, 
              MySQLiteHelper.KEY_EMAIL}, MySQLiteHelper.COLUMN_ID + " =" + (id-1),null,null,null, null );

因此,通过调用cursor.getCount()来检查光标是否为空。如果这是零,则光标为空。

编辑:编辑了整个答案,以明确我的观点,并删除错误的假设。

编辑2:我想我现在知道你想要达到的目标。试试这个而不是你的代码:

public List<String> getRow(int id)   {
      List<String> row = new ArrayList<String>();
      Cursor cursor = database.query(MySQLiteHelper.TABLE_COMMENTS, new String[] {MySQLiteHelper.COLUMN_ID, 
              MySQLiteHelper.KEY_NAME, MySQLiteHelper.KEY_STREET, MySQLiteHelper.KEY_CITY, MySQLiteHelper.KEY_PHONE, 
              MySQLiteHelper.KEY_EMAIL}, MySQLiteHelper.COLUMN_ID + " =" + (id-1),null,null,null, null );

      while (cursor.moveToNext()) {
          //Get columns from cursor
          String name = cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_NAME));
          String street = cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_STREET));
          String city = cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_CITY));
          String phone = cursor.getString(cursor.getColumnIndex(MySQLiteHelper.KEY_PHONE));
          String email = cursor.getString(cursor.getColumnindex(MySQLiteHelper.KEY_EMAIL));
          //add columns to row list
          row.add(name);
          row.add(address);
          row.add(city);
          row.add(phone);
          row.add(email);
      }

      cursor.close();

      return row;
 }

但这只有在游标不为空时才有效!

答案 1 :(得分:0)

是的,这是正确的但是对于insert()而不是对于query()。是的问题是你只是用getString(1)添加name列,用getLong(0)添加id。最好通过getColumnIndex(columnName)检索columIndex(请参阅我的回答),这样如果更改query()中检索到的列的顺序,这不会中断。你会更好地了解自己在做什么。如果您对其他事情有更多疑问,请在新问题主题中询问他们。玩得开心!