我在将表从SQLCipher数据库显示到ListView时遇到了一些麻烦。
我的程序,现在,只允许用户添加"秘密"到数据库。当我的数据库是SQLite时,我能够查看数据,但在转移到SQLCipher后,我遇到了一些错误。
以下是我遇到的一些错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.matc.secretkeeper/edu.matc.secretkeeper.ListData}: java.lang.IllegalStateException: get field slot from row 0 col 1 failed
和此:
Finalizing a Cursor that has not been deactivated or closed. database = /data/user/0/edu.matc.secretkeeper/databases/secrets1.db, table = null, query = SELECT * FROM secretTable
net.sqlcipher.database.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
这是我的代码,可以帮助您排查问题。
这是我的ListData.java类:
public class ListData extends AppCompatActivity {
private static final String TAG = "activity_list_data" ;
MyDBHandler myDB;
private ListView myListView;
Button refreshList, goHome;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_data);
myListView = (ListView) findViewById(R.id.listView);
myDB = new MyDBHandler(this);
populateListView();
refreshList = (Button) findViewById(R.id.refreshListBtn); //refresh button
refreshList.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent myIntent = new Intent(ListData.this,
ListData.class);
startActivity(myIntent);
}
});
goHome = (Button) findViewById(R.id.homeBtn); //gohome button
goHome.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent myIntent = new Intent(ListData.this,
MainActivity.class);
startActivity(myIntent);
}
});
}
//this doesnt seem to be populating the list view
private void populateListView() {
Log.d(TAG, "populateListView: Displaying data in the ListView.");
//get the data and append to a list
Cursor data = myDB.getData();
ArrayList<String> listData = new ArrayList<>();
while(data.moveToNext()){
//get the value from the database in column 1
//then add it to the ArrayList
listData.add(data.getString(1));
data.close(); //close cursor
}
Log.d(TAG, "array list while loop completed");
//create the list adapter and set the adapter
ListAdapter adapter = new ArrayAdapter<>(this,
android.R.layout.simple_list_item_1, listData);
myListView.setAdapter(adapter);
//set an onItemClickListener to the ListView
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int
i, long l) {
String secret = adapterView.getItemAtPosition(i).toString();
Log.d(TAG, "onItemClick: You Clicked on " + secret);
Cursor data = myDB.getItemID(secret); //get the id associated
with that secret
int itemID = -1;
while(data.moveToNext()){
itemID = data.getInt(0);
}
if(itemID > -1){
Log.d(TAG, "onItemClick: The ID is: " + itemID);
Intent editScreenIntent = new Intent(ListData.this,
EditData.class);
editScreenIntent.putExtra("id",itemID);
editScreenIntent.putExtra("secret",secret);
startActivity(editScreenIntent);
}
else{
toastMessage("No ID associated with that secret");
}
}
});
}
private void toastMessage(String message){
Toast.makeText(this,message, Toast.LENGTH_SHORT).show();
}
}
MyDBHelper类中的getData方法:
public Cursor getData(){
SQLiteDatabase db = this.getWritableDatabase("temp123");
String query = "SELECT * FROM " + TABLE_SECRET;
Cursor data = db.rawQuery(query,null);
Log.d("Cursor Object", DatabaseUtils.dumpCursorToString(data));
db.close();
return data;
}
如果我需要添加任何细节以便描绘更好的图片,请告诉我。
热烈的问候,
Ĵ
答案 0 :(得分:0)
在我的populateListView()
方法中,我关闭了while
循环内的光标。在while循环之外移动data.close()
之后,一切正常。