我的应用程序正在使用模拟器,而不是在设备上。 log cat说android.database.CursorIndexOutOfBoundsException

时间:2013-11-26 19:11:27

标签: android sqlite logcat

我无法在数据库中找到错误的位置。我正在制作的应用程序在模拟器模拟器上工作,但现在我尝试在4.1.2平台上的移动设备上运行它,它立即获得强制关闭消息。在我开始使用数据库之前,它在一个模拟器和移动设备上运行良好。我保留了最低要求SDK:API 11:Android 3.0(Honeycomb)和Target SDK:API 18:Android 4.3。我也在Manifest文件中添加了活动。

11-25 01:53:50.047: E/Trace(26246): error opening trace file: No such file or directory (2)    
11-25 01:53:50.057: D/ActivityThread(26246): setTargetHeapUtilization:0.25    
11-25 01:53:50.057: D/ActivityThread(26246): setTargetHeapIdealFree:8388608    
11-25 01:53:50.057: D/ActivityThread(26246): setTargetHeapConcurrentStart:2097152    
11-25 01:53:50.117: D/AndroidRuntime(26246): Shutting down VM    
11-25 01:53:50.117: W/dalvikvm(26246): threadid=1: thread exiting with uncaught exception (group=0x40ecf378)    
11-25 01:53:50.127: E/AndroidRuntime(26246): FATAL EXCEPTION: main
11-25 01:53:50.127: E/AndroidRuntime(26246): java.lang.RuntimeException: Unable to create application my.app.cal.CalApplication: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4196)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.app.ActivityThread.access$1300(ActivityThread.java:138)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1267)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.os.Looper.loop(Looper.java:213)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.app.ActivityThread.main(ActivityThread.java:4787)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at java.lang.reflect.Method.invokeNative(Native Method)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at java.lang.reflect.Method.invoke(Method.java:511)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at dalvik.system.NativeStart.main(Native Method)
11-25 01:53:50.127: E/AndroidRuntime(26246): Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:418)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:74)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at my.app.cal.CalApplication.readWeighingDetailFromDB(CalApplication.java:45)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at my.app.cal.CalApplication.onCreate(CalApplication.java:26)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999)
11-25 01:53:50.127: E/AndroidRuntime(26246):    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4193)
11-25 01:53:50.127: E/AndroidRuntime(26246):    ... 10 more

以下是我的数据库文件: WeighingDetailDatabaseHelper.java:

package my.app.cal;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class WeighingDetailDatabaseHelper extends SQLiteOpenHelper {

    public static final String DB_NAME = "MyWeighingDetail.SQLite";
    public static final int DB_VERSION = 1;
    public static String WEIGHING_DETAIL_TABLE ="WeighingDetailTable";
    public static String RECORD_ID = "ID";
    public static String DATE ="Date";
    public static String WEIGHT = "Weight";


    public WeighingDetailDatabaseHelper(Context context){
        super (context, DB_NAME, null, DB_VERSION);

    }

    @Override
    public void onCreate(SQLiteDatabase weighingDetailDB) {

        String sqlStatement = "create table " + WEIGHING_DETAIL_TABLE
                + " (" 
                + RECORD_ID + " integer primary key autoincrement not null,"
                + DATE + " integer,"
                + WEIGHT + " float"
                + ");";

        Log.d("Weighing Database", sqlStatement);

        weighingDetailDB.execSQL(sqlStatement);

    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {


    }

}

WeighingDetail.java:

package my.app.cal;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;

public class WeighingDetail implements Comparable<WeighingDetail> {

    private long id;
    private float weight;
    private Date date;
    private float runningAverage;




    public WeighingDetail(float weight, Date date) {
        this.weight = weight;
        this.date = date;
    }

    public WeighingDetail(long id, long dateEpoch, float weight) {
        this.id = id;
        setDateEpoch(dateEpoch);
        this.weight = weight;
        this.date = date;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }



    public float getWeight() {
        return weight;
    }

    public void setWeight(float weight) {
        this.weight = weight;
    }

    public Date getDate() {
        return date;
    }

    public long getDateEpoch(){
        return date.getTime()/1000;

    }
    public void setDateEpoch(long seconds){
        date = new Date(seconds * 1000);
    }

    public void setDate(Date date) {
        this.date = date;
    }


    public float getRunningAverage() {
        return runningAverage;
    }


    public void setRunningAverage(float runningAverage) {
        this.runningAverage = runningAverage;
    }
    public float sumofWeight() {
        return weight;  //Its just the weight itself, its used to calculate the running average weight later
    }

    public float calculateWeightAverage() {
        return weight;// Its the weight itself, used in averageEditText as well as for calculating total of the weights till now added
    }

    public boolean equals(Object that){
        WeighingDetail wd = (WeighingDetail) that;

        return this.date.equals(wd.date);
    }
    @Override
    public int compareTo(WeighingDetail that) {
        int difference;
        difference = this.date.compareTo(date);
        return difference;
    }

    public static void updateRunningAverage (ArrayList<WeighingDetail> allWeighingDetail) {

        int weeks = 1;
        float total = 0;

        Collections.sort(allWeighingDetail);

        if(allWeighingDetail.size() >0){
            for(WeighingDetail wd : allWeighingDetail){
                total +=wd.calculateWeightAverage();
                wd.setRunningAverage((float) total / (weeks));// first it was weeks = 3
                weeks++;
            }
        }
    }

    public String toString() {
        String result;
        //"ID:" + id + " " + 

        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM);
        result = df.format(date) + " " + weight  
                + String.format("%.1f", runningAverage);
        return result;
    }


}

show history按钮显示数据库以及运行平均值,因此我的java文件是ShowHistory.java。

package my.app.cal;

import java.util.ArrayList;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;

public class HistoryActivity extends ListActivity {

    private ArrayList<WeighingDetail> allWeighingDetail; //added an instance method to activity
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.history_layout);

        //get the data from the App
        CalApplication app = (CalApplication) getApplication();
        allWeighingDetail = app.getAllWeighingDetail();
        WeighingDetail.updateRunningAverage (allWeighingDetail);

        // View ------  Adapter    -----  Data

        setListAdapter(
                new ArrayAdapter<WeighingDetail>(this,
                        android.R.layout.simple_list_item_1,
                        allWeighingDetail)



        );

    }
}

CalApplication.java

package my.app.cal;

import java.util.ArrayList;

import android.app.Application;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import static my.app.cal.WeighingDetailDatabaseHelper.*;
public class CalApplication extends Application {

    private ArrayList<WeighingDetail> allWeighingDetail;
    private SQLiteDatabase weighingDetailDB;

    @Override
    public void onCreate() {

        super.onCreate();

        WeighingDetailDatabaseHelper databaseHelper = new WeighingDetailDatabaseHelper(this);
        weighingDetailDB = databaseHelper.getWritableDatabase();

        // TODO get the data out of the database

        readWeighingDetailFromDB ();

    }

    private void readWeighingDetailFromDB() {

        allWeighingDetail = new ArrayList<WeighingDetail>();

        Cursor weighingDetailCursor;

        weighingDetailCursor = weighingDetailDB.query(WEIGHING_DETAIL_TABLE,
                new String[]{RECORD_ID, DATE, WEIGHT},
                null, null, null, null,DATE);

        weighingDetailCursor.moveToFirst();
        WeighingDetail tempWD;

        if(weighingDetailCursor.isAfterLast()){
            do{
                long id = weighingDetailCursor.getLong(0);
                long dateEpoch = weighingDetailCursor.getLong(1);
                float weight = weighingDetailCursor.getFloat(2);

                tempWD = new WeighingDetail(id, dateEpoch, weight);

                allWeighingDetail.add(tempWD);

                Log.d("Weighing Database", tempWD.toString());
            }while(weighingDetailCursor.moveToNext());

        }
        weighingDetailCursor.close();

    }

    public void addWeighingDetail(WeighingDetail weighingDetail){

        assert weighingDetail != null;

        ContentValues cv = new ContentValues();//object that will put the data to the db
        cv.put(WeighingDetailDatabaseHelper.DATE, weighingDetail.getDateEpoch());//USE EPOCH
        cv.put(WeighingDetailDatabaseHelper.WEIGHT, weighingDetail.getWeight());

        Log.d("Weighing Database", "Before Inserting a record" + weighingDetail);

        long idPassedBack = weighingDetailDB.insert(WeighingDetailDatabaseHelper.WEIGHING_DETAIL_TABLE, null, cv);
        weighingDetail.setId(idPassedBack);

        Log.d("Weighing Database", "After Inserting a record" + weighingDetail);
        allWeighingDetail.add(weighingDetail);

    }

    public ArrayList<WeighingDetail> getAllWeighingDetail() {
        return allWeighingDetail;
    }

    private void setAllWeighingDetail(ArrayList<WeighingDetail> allWeighingDetail) {
        this.allWeighingDetail = allWeighingDetail;
    }
}

2 个答案:

答案 0 :(得分:0)

在尝试从光标读取任何内容之前,请检查moveToFirst()的返回值。看起来好像没有返回任何结果。

if (cursor.moveToFirst()) {
//do your effort
}

答案 1 :(得分:0)

处理游标时始终使用此条件:

if( cursor != null && cursor.moveToFirst() ) {
//do operations with records
}

检查光标是否为空。如果它不为null,则将光标移动到第一个记录。这里的光标可能为null(没有记录)。