Android Studio - SQLite 插入冻结

Posted

技术标签:

【中文标题】Android Studio - SQLite 插入冻结【英文标题】:Android Studio - SQLite insert freeze 【发布时间】:2020-07-22 12:52:49 【问题描述】:

我正在尝试制作一个 SQLite 应用程序,我可以在其中添加和删除行,并且应该立即打印出来。 当我按下其中一个按钮时,模拟器会冻结。 我没有错误,logcat 没有显示任何内容。 我在模拟器和真机上试了一下,结果一样。

这是我没有导入的 MainActivity:

public class MainActivity extends AppCompatActivity 
    //in the tutorial these variables were not private
    private EditText et1;
    private TextView tv1;
    private MyDBHandler dbHandler;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        et1 = (EditText) findViewById(R.id.editText);
        tv1 = (TextView) findViewById(R.id.textView);
        dbHandler = new MyDBHandler(this, null, null, 1);
    

    public void insertButtonClicked(View view) 
        Products product = new Products(et1.getText().toString());
        dbHandler.addProduct(product);
        printDatabase();
    

    public void deleteButtonClicked(View view) 
        String inputText = et1.getText().toString();
        dbHandler.deleteProduct(inputText);
        printDatabase();
    

    public void printDatabase() 
        String dbString = dbHandler.databaseToString();
        tv1.setText(dbString);
        et1.setText("");
    

类产品:

public class Products 
    private int _id;
    private String _productname;

    public Products(String productname) 

        this._productname = productname;
    

    public int get_id() 
        return _id;
    

    public String get_productname() 
        return _productname;
    

    public void set_id(int _id) 
        this._id = _id;
    

    public void set_productname(String productname) 

        this._productname = productname;
    

没有导入的 myDBHandler 类:



public class MyDBHandler extends SQLiteOpenHelper 
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "products.db";
    public static final String TABLE_PRODUCTS = "products";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_PRODUCTNAME = "_productname";

    public MyDBHandler(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) 
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    

    @Override
    public void onCreate(SQLiteDatabase db) 
        String query = "CREATE TABLE " + TABLE_PRODUCTS + " (" +
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_PRODUCTNAME + " TEXT" +
                ");";
        db.execSQL(query);
    

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_PRODUCTS);
        onCreate(db);
    

    //add a new row to the database
    public void addProduct(Products product) 
        ContentValues values = new ContentValues();
        values.put(COLUMN_PRODUCTNAME, product.get_productname());
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_PRODUCTS, null, values);
    

    //delete a row from the database
    public void deleteProduct(String productName) 
        SQLiteDatabase db = getWritableDatabase();
        db.execSQL("DELETE FROM " + TABLE_PRODUCTS + " WHERE " + COLUMN_PRODUCTNAME +
                " =\"" + productName + "\";");
    

    //print out the database as a string

    public String databaseToString() 
        String dbString = "";
        SQLiteDatabase db = getWritableDatabase();
        //the tutorial guy did a "WHERE 1" instead of the ";" but that also does not work
        String query = "SELECT * FROM " + TABLE_PRODUCTS + ";";
        Cursor c = db.rawQuery(query, null);
        c.moveToFirst();

        while(!c.isAfterLast()) 
            if(c.getString(c.getColumnIndex("_productname")) != null) 
                dbString += c.getString(c.getColumnIndex("_productname"));
                dbString += "\n";
            
        
        c.close();
        db.close();
        return dbString;
    

xml文件最重要的部分:


    <EditText
        android:id="@+id/editText"
        android:layout_
        android:layout_
        android:layout_marginTop="24dp"
        android:ems="10"
        android:inputType="textPersonName"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:hint="@string/edittexthint"
        android:importantForAutofill="no"/>

    <Button
        android:id="@+id/button"
        android:layout_
        android:layout_
        android:layout_marginTop="24dp"
        android:onClick="insertButtonClicked"
        android:text="@string/insert_msg"
        app:layout_constraintStart_toStartOf="@+id/editText"
        app:layout_constraintTop_toBottomOf="@+id/editText" />

    <Button
        android:id="@+id/button2"
        android:layout_
        android:layout_
        android:layout_marginTop="24dp"
        android:onClick="deleteButtonClicked"
        android:text="@string/delete_msg"
        app:layout_constraintEnd_toEndOf="@+id/editText"
        app:layout_constraintTop_toBottomOf="@+id/editText" />

    <TextView
        android:id="@+id/textView"
        android:layout_
        android:layout_
        android:layout_marginTop="24dp"
        android:text="@string/tv_content"
        app:layout_constraintTop_toBottomOf="@+id/button"
        app:layout_constraintStart_toStartOf="@+id/button"/>

</androidx.constraintlayout.widget.ConstraintLayout>

【问题讨论】:

【参考方案1】:

这段代码中的一个问题可能是我在 SQL 语句中添加了不必要的分号。 我取得了一些进步,但使用了一种不同且更简单的方法,没有表的类。

【讨论】:

【参考方案2】:

在您的databaseToString() 方法中,您正在读取while(!c.isAfterLast()) 循环中的光标,您忘记将光标移动到带有c.moveToNext() 的新行。因此,while 循环永远不会终止。

【讨论】:

以上是关于Android Studio - SQLite 插入冻结的主要内容,如果未能解决你的问题,请参考以下文章

[转]Android Studio SQLite Database Multiple Tables Example

从 Android Studio 浏览 SQLite 数据库 [关闭]

android studio中ListView与SQLite的结合使用

如何从 android studio 中的 SQLite 插入中删除不需要的字符

Android Studio - 线程完成后从 SQLite 获取数据

使用 SQL/SQLite 工具箱 Visual Studio 2019 在 SQLite 数据库和 Xamarin.Android 项目之间建立连接