1

数日間解決できない問題があります。データベースとの間でデータを読み書きするためのメソッドを作成しましたが、見つけられない問題があります。コードは次のとおりです。

    public void writeEntry(String name, long period, long frequency, long recievingTime, String stats){
        ContentValues cv = new ContentValues();
        cv.put(KEY_NAME, name);
        cv.put(KEY_PERIOD, period);
        cv.put(KEY_FREQUENCY, frequency);
        cv.put(KEY_RECIEVINGTIME, recievingTime);
        cv.put(KEY_STATS, stats);
        myDatabase.insert(DATABASE_TABLE, null, cv);
    }

    public Cursor query(String[] columns, String selection, String[] selectionArgs, String groupBy) {
        // TODO Auto-generated method stub
        Cursor c = myDatabase.query(DATABASE_TABLE, columns, selection, selectionArgs, groupBy, null, null);
        return c;
    }

dbにデータを書き込む方法は次のとおりです。

 public void save(){
    sharedPrefs = context.getSharedPreferences(SPNAME, 0);
    Log.v(" info", sharedPrefs.getAll().toString());
    Database database = new Database(context);
    database.open();
    database.writeEntry(
            sharedPrefs.getString(NAME, "No data was found"), 
            sharedPrefs.getLong(PERIOD, 0),
            sharedPrefs.getLong(FREQUENCY, 0), 
            sharedPrefs.getLong(RECIEVINGTIME, 0), 
            sharedPrefs.getString(STATS, "No data was found")
            );
    database.close();
}

そして、これが私がそれを取得する方法です:

 public List<String> getReportInfo(String rowId){
    List<String> result = new ArrayList<String>();
    database = new Database(context);
    database.open();
    cursor = database.query(new String[]{
            Database.KEY_NAME,
            Database.KEY_PERIOD,
            Database.KEY_FREQUENCY,
            Database.KEY_RECIEVINGTIME,
            Database.KEY_STATS},
            Database.KEY_ROWID +" = "+rowId, null, null);
    for(cursor.moveToFirst(); cursor.isAfterLast(); cursor.moveToNext()){
        result.add(cursor.getString(cursor.getPosition()));
    }
    cursor.close(); 
    database.close();   
    return result;
}

後で、getViewメソッドのBaseAdapterのdbからのデータを使用して、次のようにListViewにデータを入力します。

  public class MyArrayAdapter extends BaseAdapter{  

    private Activity activity;
    private LayoutInflater inflater;
    TextView tvMyReportsPeriod, tvMyReportsFrequency, tvMyReportsReceivingTime, tvMyReportTitle;
    LinearLayout llMyReportsStats;
    Database database;
    Report report;
    Cursor cursor;

    public MyArrayAdapter(Activity a) {
        super();
        // TODO Auto-generated constructor stub
        activity = a;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        report = new Report(activity);
    }

    public int getCount() {
        // TODO Auto-generated method stub
        int count = 2;
        try{
        cursor = database.query(new String[]{Database.KEY_NAME}, null, null, null);
        count= cursor.getCount();
        cursor.close();
        }catch(Exception e){}
        return count;
    }

    public Object getItem(int position) {
        // TODO Auto-generated method stub
        List<String> list = report.getReportInfo(String.valueOf(position));
        return list;
    }

    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        if(convertView==null){
            convertView = inflater.inflate(R.layout.my_reports_view_holder, null, false);

            tvMyReportsPeriod = (TextView)convertView.findViewById(R.id.tvMyReportsPeriod);
            tvMyReportsFrequency = (TextView)convertView.findViewById(R.id.tvMyReportsFrequency);
            tvMyReportsReceivingTime = (TextView)convertView.findViewById(R.id.tvMyReportsReceivingTime);
            tvMyReportTitle = (TextView)convertView.findViewById(R.id.tvMyReportTitle);
            llMyReportsStats = (LinearLayout)convertView.findViewById(R.id.llMyReportsStats);

                List<String> data = report.getReportInfo(String.valueOf(position));
                if(data!=null){
                    tvMyReportTitle.setText(data.get(0));
                    tvMyReportsPeriod.setText(report.convertMillis(Long.parseLong(data.get(1))));
                    tvMyReportsFrequency.setText(report.convertMillis(Long.parseLong(data.get(2))));
                    tvMyReportsReceivingTime.setText(report.convertMillis(Long.parseLong(data.get(3))));
                    String[] stats = data.get(4).toString().split(" ");             
                    for(int x=0; x<stats.length; x++){
                        TextView textView = new TextView(activity);
                        for(Constants dc: Constants.values()){
                            if(dc.getId()==Integer.parseInt(stats[x])){
                                textView.setText(dc.getText());
                            }
                        }
                        llMyReportsStats.addView(textView); 
                    }
                }else{System.out.println("ERROR: data=null");}
        }
        return convertView;
    }

ListViewアイテムごとに一度にdbから1行を取得することを期待していますが、代わりに次のlogcatを取得します。

09-27 11:03:03.173: E/AndroidRuntime(25768): android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at com.dailyreports.ainius.Report.getReportInfo(Report.java:107)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at com.dailyreports.ainius.MyReports$MyArrayAdapter.getView(MyReports.java:88)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.AbsListView.obtainView(AbsListView.java:1430)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.ListView.measureHeightOfChildren(ListView.java:1216)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.ListView.onMeasure(ListView.java:1127)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.View.measure(View.java:8313)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1017)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:386)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.View.measure(View.java:8313)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.View.measure(View.java:8313)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.LinearLayout.measureVertical(LinearLayout.java:531)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.LinearLayout.onMeasure(LinearLayout.java:309)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.View.measure(View.java:8313)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:3138)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.widget.FrameLayout.onMeasure(FrameLayout.java:250)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.View.measure(View.java:8313)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.ViewRoot.performTraversals(ViewRoot.java:841)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1861)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.os.Looper.loop(Looper.java:123)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at android.app.ActivityThread.main(ActivityThread.java:3729)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at java.lang.reflect.Method.invokeNative(Native Method)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at java.lang.reflect.Method.invoke(Method.java:507)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:874)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:632)
09-27 11:03:03.173: E/AndroidRuntime(25768):    at dalvik.system.NativeStart.main(Native Method)

どこに問題があるのか​​わからない。助けてください。

4

4 に答える 4

0

cursor.moveToFirst()trueが返されたことを確認する必要があります。

実行しているクエリに結果がない場合は、そのCursorIndexOutOfBoundsException例外が発生します...

また、アプリアンが指摘したように。cursor.getStringカーソルの位置ではなく、列のインデックスを引数として取ります。

に置き換えresult.add(cursor.getString(cursor.getPosition()));ますresult.add(cursor.getString(Database.KEY_STATS));

于 2012-09-27T08:05:26.093 に答える
0

これcursor.getString(cursor.getPosition())は投稿したエラーの原因ではありませんが、後で他のエラーが発生します。ドキュメントを読むと、予想されるパラメーターは列インデックスであり、行インデックスではありません。

あなたが観察しているエラーは、おそらく moveToFirst が False を返しますが、テストしていないという事実が原因です。あなたのデータベースは空です。

編集

もう一度読んだ後、 for ループは(非常に見栄えが良いですが)完全にオフになっています。isAfterLast をループ条件としてテストしますが、せいぜい終了条件にする必要があります。move to first の結果をチェックしません。moveToNext の結果をチェックしません。

forループを次のように置き換えます

while(cursor.moveToNext()) {
    // Do stuff
}
于 2012-09-27T08:09:10.587 に答える
0

問題はここにもあるようです:

result.add(cursor.getString(cursor.getPosition()));

フェッチされたレコードの数がクエリで要求された列の数よりも多い場合、エラーがスローされるためです。これは、カーソルから値を読み取る方法ではありません。実際、どの列の値を読み取る必要があるかを特定する必要があります。例えば:

result.add(cursor.getString(cursor.getColumnIndex(Database.KEY_NAME)));

または、おそらく固定インデックス値を使用します。たとえば、次のようになります。

result.add(cursor.getString(0));
于 2012-09-27T08:09:30.630 に答える
0

編集:あなたが望むのは、DBから単一の行を取得することのようです。

目的を達成するためMyObjectに代わりに使用する必要があります。List<String>

の例を次に示します。POJOMyObjectを参照してください。

public class MyObject {
    String name = "", stats = "";
    Long period = 0, frequency = 0, receivingtime = 0;

    // empty constructor
    public MyObject() {
    }

    // simple getter method
    public String getName() {
        return name;
    }

    // simple setter method
    public void setName(String name) {
        this.name = name;
    }

    ...
    // You may want to override toString() method when implementing searching or using ArrayAdapter
    @Override
    public String toString() {
        return name + " " + stats;
    }
}

に変更getReportInfoします。

public MyObject getReportInfo(String rowId){
    MyObject result = new MyObject();
    database = new Database(context);
    database.open();
    cursor = database.query(new String[]{
            Database.KEY_NAME,
            Database.KEY_PERIOD,
            Database.KEY_FREQUENCY,
            Database.KEY_RECIEVINGTIME,
            Database.KEY_STATS},
            Database.KEY_ROWID +" = "+rowId, null, null);
    // this will prevent CursorIndexOutofBoundsException
    if (cursor.moveToFirst()) {
        result.setName(cursor.getString(0));
        result.setPeriod(cursor.getLong(1));
        result.setFrequency(cursor.getLong(2));
        result.setReceivingTime(cursor.getLong(3));
        result.setStats(cursor.getString(4));
    }
    cursor.close(); 
    database.close();   
    return result;
}
于 2012-09-27T08:32:59.930 に答える