0

我觉得我错过了一些简单而愚蠢的东西。我有一个列表视图,顶部有几个按钮。列表视图最初填充了数据。当您单击按钮时,列表视图应该根据 Where 语句中更改的变量填充其自身。实际上,我可能只是开始一个新的列表活动,但我觉得有更好的方法。

我一直在阅读,CursorAdapter.changeAdapter()notifydatasetchanged()我还没有实现这个,因为我有一个更基本的问题。

我可以成功查询数据库并在列表中显示静态结果。当我尝试将流程分解为多个步骤时,我遇到了 ERROR: Invalid statement in fillWindow. 据我所知,这是由于不正确地关闭游标数据库和数据库助手造成的,因此人们使用内容提供程序。

现在我只是想让这个工作。

    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;

你创建了一个游标对象,但在你使用它(数据库的这个组件)之前关闭了你的数据库连接,如果你愿意的话,这会使它变得无用或为空。通常你关闭游标,然后关闭数据库。但这并没有引发错误。该错误具体是因为您将此光标连接到 cursorAdapter 试图用任何内容填充您的 listView 。移动它,它应该消失了。

那么你把它移到哪里呢?如果你有一个光标连接到 listView,它需要一直打开,否则你会得到另一个错误,说“试图重新打开一个已经关闭的对象”。我建议将onDestroy()listView 也放入其中。

于 2012-11-15T12:19:18.470 回答
0

耶解决了。芒果是完全正确的。感谢您建议在销毁时关闭光标。我不确定 super.close() 行是否关闭了我的光标。但我会调查的。我还将把数据库查询放在异步任务中,以备不时之需。

我只是移动了创建新 SimpleCursorAdapter 的两行并将列表视图设置到 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 关闭了所有连接。谢谢芒果。我昨晚解决了这个问题,但无法发布。谢谢好先生的解释。如果您对不断创建新的 cursoradapter 有任何见解,我会很高兴看到它。也许我需要以某种方式修复 super.close() 命令。

于 2012-11-15T18:58:03.390 回答