【问题标题】:select in where clause force closing android app -sqlite-在where子句中选择强制关闭android应用-sqlite-
【发布时间】:2020-08-21 09:44:35
【问题描述】:

我正在尝试在 sqlite 中查询我的数据库以获取 android 应用程序,但应用程序强制关闭。 我有一个列表视图,显示有关人员的信息。 (此信息是通过查询我的整个有效数据库来检索的)。现在,当用户单击列表视图中的一个项目时,我试图打开另一个活动,该用户信息预先填充在屏幕上。 为此,我在项目单击侦听器中使用位置变量,然后从我的表中选择我的表中我的 ID 等于位置的所有内容。

这是我的数据库助手类

package com.example.assignment1;

import android.database.sqlite.SQLiteDatabase;
import android.content.Context;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import java.util.ArrayList;

public class databaseManager {
    public static final String DB_NAME = "Friends";
    public static final String DB_TABLE = "friendList";
    public static final int DB_VERSION = 1;
    private static final String CREATE_TABLE = "CREATE TABLE " + DB_TABLE +
            " (code INTEGER PRIMARY KEY AUTOINCREMENT , friendName TEXT NOT NULL, friendAge INTEGER, friendGender TEXT NOT NULL, friendAddress TEXT NOT NULL);";
    private SQLHelper helper;
    private SQLiteDatabase db;
    private Context context;
    public databaseManager(Context c) {
        this.context = c;
        helper = new SQLHelper(c);
        this.db = helper.getWritableDatabase();
    }
    public databaseManager openReadable() throws android.database.SQLException {
        helper = new SQLHelper(context);
        db = helper.getReadableDatabase();
        return this;
    }
    public void close() {
        helper.close();
    }
    public boolean addRow( String name, int age,String gender, String address) {

        ContentValues newFriend = new ContentValues();
        newFriend.put("friendName", name);
        newFriend.put("friendAge", age);
        newFriend.put("friendGender", gender);
        newFriend.put("friendAddress", address);

        db.insert(DB_TABLE,null,newFriend);
        db.close();
        return true;
    }
    
    public ArrayList<String> retrieveRow(int ID){
        ArrayList<String> result = new ArrayList<String>();
        String[] columns = new String[] {"code", "friendName", "friendAge","friendGender","friendAddress"};
        Cursor cursor = db.query(DB_TABLE, columns, "code" + "=" + ID, null, null, null, null);
        cursor.moveToFirst();
        while (cursor.isAfterLast() == false) {
            result.add(cursor.getInt(0) + ", " + cursor.getString(1) + ", " +
                    cursor.getInt(2) + ", "+ cursor.getString(3) + ", "+cursor.getString(4)+ "\n");
            cursor.moveToNext();
        }
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
        return result;
    }
    public ArrayList<String>retrieveRows() {
        ArrayList<String> result = new ArrayList<String>();
        String[] columns = new String[] {"code", "friendName", "friendAge","friendGender","friendAddress"};
        Cursor cursor = db.query(DB_TABLE, columns, null, null, null, null, null);
        cursor.moveToFirst();
        while (cursor.isAfterLast() == false) {
           result.add(cursor.getInt(0) + ", " + cursor.getString(1) + ", " +
                    cursor.getInt(2) + ", "+ cursor.getString(3) + ", "+cursor.getString(4)+ "\n");
            cursor.moveToNext();
        }
        if (cursor != null && !cursor.isClosed()) {
            cursor.close();
        }
        return result;
    }

    public class SQLHelper extends SQLiteOpenHelper {
        public SQLHelper (Context c) {
            super(c, DB_NAME, null, DB_VERSION);
        }
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATE_TABLE);
        }
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.w("Products table", "Upgrading database i.e. dropping table and re-creating it");
                    db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
            onCreate(db);
        }
    }

}

如您所见,我复制了用于检索所有功能的相同代码并添加了 where 子句。

这就是我使用这个功能的方式

package com.example.assignment1;

import android.app.AppComponentFactory;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;

public class viewFriends extends AppCompatActivity {
    private ListView listView;
    private databaseManager mydb;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.viewfriendlist);
        listView = (ListView)findViewById(R.id.listView);
        mydb = new databaseManager(viewFriends.this);
        mydb.openReadable();
        displayFriendList();

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String pos = (String)parent.getItemAtPosition(position);
            int poss = position +1;

               Intent intent = new Intent(getApplicationContext(),editOrDelete.class);
               ArrayList<String> result1=mydb.retrieveRow(poss);


                Toast.makeText(getApplicationContext(),pos,Toast.LENGTH_SHORT).show();
               //startActivity(intent);

            }
        });
        mydb.close();



    }

    public void displayFriendList(){
        ArrayList<String> result = mydb.retrieveRows();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, result);
        listView.setAdapter(adapter);
    }



}

这是我的日志

 08-21 19:41:39.719 17562-17562/com.example.assignment1 E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.assignment1, PID: 17562
        java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/user/0/com.example.assignment1/databases/Friends
            at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
            at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1158)
            at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
            at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1202)
            at com.example.assignment1.databaseManager.retrieveRow(databaseManager.java:53)
            at com.example.assignment1.viewFriends$1.onItemClick(viewFriends.java:42)
            at android.widget.AdapterView.performItemClick(AdapterView.java:310)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1145)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:3042)
            at android.widget.AbsListView$3.run(AbsListView.java:3879)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:5417)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

非常感谢任何帮助

【问题讨论】:

    标签: android sqlite android-studio


    【解决方案1】:

    问题是您在填充列表后立即在您的 db 对象上调用 close(),因此当您稍后尝试重用该对象以获取特定人员的数据时,您会得到一个错误。在设置监听器后关闭它并不重要,因为稍后会调用监听器的代码。 请注意您的错误消息中的以下内容:

    java.lang.IllegalStateException:尝试重新打开一个已经关闭的对象:SQLiteDatabase

    您可以选择在单击列表项时重新构建数据库对象然后再次关闭它,或者在应用程序终止时一劳永逸地关闭它。

    【讨论】:

      猜你喜欢
      • 2013-05-28
      • 1970-01-01
      • 2014-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 2014-03-18
      • 1970-01-01
      相关资源
      最近更新 更多