0

シンプルでバカなものが欠けているような気がします。上部にいくつかのボタンがあるリストビューがあります。リストビューには、最初にデータが入力されます。ボタンをクリックすると、Whereステートメントで変更された変数に基づいてリストビューにデータが入力されます。実際には、新しいリストアクティビティを開始することもできますが、もっと良い方法があるように感じます。

私は読んでいますが、もっと基本的な問題があるので、まだこれを実装していませんCursorAdapter.changeAdapter()notifydatasetchanged()

データベースに正常にクエリを実行し、静的な結果をリストに表示できます。プロセスをステップに分割しようとすると、エラーが発生します:の無効なステートメントfillWindow。私が最もよく理解しているのは、これはカーソルデータベースとDBヘルパーを不適切に閉じているためであり、このため、人々はコンテンツプロバイダーを使用しています。

今のところ、私はこれを機能させようとしています。

    public class DListView extends ListActivity implements OnClickListener{

public static final String NAME = "Name";

public static final String DESCRIPT = "Description";

public static final String DATABASE_TABLE = "Table";


public static final String DAY = "Day_id";

    /** Called when the activity is first created. */
private Cursor c = null;    

private String[] colsfrom = {"_id", NAME, DESCRIPT, DAY};
private int[] to = new int[] {R.id.text01, R.id.text02, R.id.text03, R.id.text04};

public int b = 0;

public int d = 0; 

   @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drinklistview);

        View left = findViewById(R.id.left_button);
        left.setOnClickListener(this);
        View right = findViewById(R.id.right_button);
        right.setOnClickListener(this);

        Intent thisIntent = getIntent();
        b = thisIntent.getIntExtra("_b", 0); 
        //0 is the default argument is nothing is passed.
        d = thisIntent.getIntExtra("_d", 0); //same idea as above.

            c = fillList(); 

            /*this creates a new cursor adapter
            @param Context is the list context that you will be filling. 
            @param int layout is the layout that you will use for the rows
            @param Cursor is the cursor that was returned from the query
            @param from is the column names
            @param to is the layout ids that the fields will be put in. 
            @param from is the column names to map from
            @param to is the layout ids that the column fields will be put in. 
            */
            SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(this, R.layout.row, c, colsfrom, to);
            setListAdapter(myAdapter);
   }

private Cursor fillList() {
    DBHelper DbHelper = new DBHelper(this);
    Cursor cursor;
    String wHERE = "_id = " + b + " AND Day_id = " + d ; 

    try {
        myDbHelper.openDataBase();  
    }
    catch(SQLException sqle){
        throw sqle; 
    }

    cursor = myDbHelper.getDrinks(DATABASE_TABLE, colsfrom, wHERE, null, null,null, null);

    myDbHelper.close();

    return cursor;

}

fillList()の内容をonCreate()に入れると、データが正常に表示されます。私がそれを引き出すとき、それは私にエラーを与えます。なぜこうなった?誰かがこれについてもっと良い方法を持っているなら、私はそれを読みたいです。または、「今、私が間違っているのは何の愚かなことですか?ありがとう」というゲームをプレイすることもできます。

編集:DBHelperから

public void openDataBase() throws SQLException{

    //Open the database
    String myPath = DB_PATH + DB_NAME;
    myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}

    @Override
    public synchronized void close() {

        if(myDataBase != null)
            myDataBase.close();
        super.close();
    }

私の問題の行はsuper.close()だと思います。この行はデータベースとそれに関連するすべてのものを閉じます。つまり、閉じた後に使用しようとするカーソルを意味します。私は間違っているかもしれません。できれば説明してください。

4

2 に答える 2

0

あなたの問題はここにありますfillList()

myDbHelper.close(); // <--- here
return cursor;

カーソルオブジェクトを作成しますが、それ(データベースのこのコンポーネント)を使用する前にデータベース接続を閉じます。これにより、カーソルオブジェクトが使用できなくなるか、nullになります。通常、カーソルを閉じてからデータベースを閉じます。しかし、それはエラーをスローしていません。このエラーは、具体的には、このカーソルをcursorAdapterに接続して、listViewを何も入力しようとしていないためです。それを動かせば消えるはずです。

では、どこに移動しますか?listViewにカーソルを接続している場合は、カーソルを常に開いている必要があります。そうしないと、「すでに閉じているオブジェクトを再度開こうとしています」という別のエラーが発生します。onDestroy()そのときlistViewもチャックされているときに入れることをお勧めします。

于 2012-11-15T12:19:18.470 に答える
0

YaY解決しました。マンゴーは正確に正しいです。破棄時にカーソルを閉じるように提案していただきありがとうございます。super.close()行がカーソルを閉じるかどうかはわかりません。しかし、私はそれを調べます。また、キックとギグルの非同期タスクにデータベースクエリを配置します。

新しいSimpleCursorAdapterを作成した2行を移動し、リストビューをfillListメソッドに設定しただけです。

また、ボタンを実装し、最後にfillListを追加しました。これが問題を修正したコードです。単純な間違い。

private void fillList() {
DBHelper DbHelper = new DBHelper(this);
Cursor cursor;
String wHERE = "_id = " + b + " AND Day_id = " + d ; 

try {
    myDbHelper.openDataBase();  
}
catch(SQLException sqle){
    throw sqle; 
}

cursor = myDbHelper.getDrinks(DATABASE_TABLE, colsfrom, wHERE, null, null,null, null);
SimpleCursorAdapter myAdapter = new SimpleCursorAdapter(this, R.layout.row, cursor, colsfrom, to);
setListAdapter(myAdapter);
myDbHelper.close();
 }

これが、リストビューを更新するfillListを再度呼び出す場合です。

 public void onClick(View v) {
    switch(v.getId()) {

    //Mess with d based on button click
    }
    fillList();
}

これで、アプリケーションは、何かが変更されるたびに、新しい単純なカーソルアダプタを作成する必要があります。毎回新しいCursorAdapterを作成せずにこれを実装することについて誰かがアイデアを持っている場合、それは非常に役立ちますが、私の最初の問題は解決されています。ご協力ありがとうございました。スタックトレースを見たいという事実は、私が最初に提示したコードで何も悪いことをしておらず、dbHelperにすべての接続を閉じさせたことを忘れたことを教えてくれました。ありがとうマンゴー。私は昨夜これを解決しましたが、投稿できませんでした。説明ありがとうございます。新しいカーソルアダプターの絶え間ない作成についての洞察があれば、私はそれを見てとてもうれしく思います。たぶん私はなんとかしてsuper.close()コマンドを修正する必要があります。

于 2012-11-15T18:58:03.390 に答える