sql 数据库中具有多个表的活动崩溃 - Android Studio
Posted
技术标签:
【中文标题】sql 数据库中具有多个表的活动崩溃 - Android Studio【英文标题】:Activity with multiple tables in sql database crashes - Android Studio 【发布时间】:2021-11-01 04:27:12 【问题描述】:我想为我的应用程序创建一个商店,但我被困住了,因为我无法在我的 sql 数据库中保存使商品的购物工作所需的数据。我使用了三个游标,每个表一个,但是当我尝试从数据库中检索该数据时,应用程序崩溃并出现以下错误:
2021-09-02 17:57:00.195 27466-27466/? E/com.example.a1:runtime_flags 中设置的未知位:0x8000 2021-09-02 17:57:00.218 27466-27466/? E/libc:访问被拒绝查找属性“runtime.mmitest.isrunning” 2021-09-02 17:57:00.395 27466-27501/com.example.a14 E/AwareLog:AtomicFileUtils:readFileLines 文件不存在:android.util.AtomicFile@feea179 2021-09-02 17:57:00.395 27466-27501/com.example.a14 E/AwareLog:AtomicFileUtils:readFileLines 文件不存在:android.util.AtomicFile@a63cebe
这是用于购买文章的方法。如果它工作正常,当用户选择文章时会调用方法Buy()
,并使用分数、解锁文章和激活文章的变量,完成所有操作。这是Buy()
方法的代码:
public void Buy(View view)
//Database conection
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this, "administration", null, 3);
SQLiteDatabase Database= admin.getWritableDatabase();
//Database query
Cursor row = Database.rawQuery("select * from saved_data ", null);
Cursor row2 = Database.rawQuery("select * from unlocked_articles", null);
Cursor row3 = Database.rawQuery("select * from activated_articles", null);
ContentValues record = new ContentValues();
final Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale);
if (row.moveToFirst()) //If db is not empty...
int score = row.getInt(2);
if(row2.moveToFirst())
int art0_unlock = row2.getInt(0); //One variable, one article
int art1_unlock = row2.getInt(1);
int art2_unlock = row2.getInt(2);
int art3_unlock = row2.getInt(3);
int art4_unlock = row2.getInt(4);
if(row3.moveToFirst())
int art0_activ = row3.getInt(0);
int art1_activ = row3.getInt(1);
int art2_activ = row3.getInt(2);
int art3_activ = row3.getInt(3);
int art4_activ = row3.getInt(4);
if (art0.isSelected()) ... //Operations for the purchase are here, not the problem
//For saving data
record.put("score", score);
record.put("art0_unlock", art0_unlock);
record.put("art1_unlock", art1_unlock);
record.put("art2_unlock", art2_unlock);
record.put("art3_unlock", art3_unlock);
record.put("art4_unlock", art4_unlock);
record.put("art0_activ", art0_activ);
record.put("art1_activ", art1_activ);
record.put("art2_activ", art2_activ);
record.put("art3_activ", art3_activ);
record.put("art4_activ", art4_activ);
Database.update("saved_data", record, null, null);
Database.update("unlocked_articles", record, null, null);
Database.update("activated_articles", record, null, null);
tv_score.setText(score);
row.close();
row2.close();
row3.close();
else //If activated_articles is empty...
record.put("art0_activ", 0);
record.put("art1_activ", 0);
record.put("art2_activ", 0);
record.put("art3_activ", 0);
record.put("art4_activ", 0);
Database.insert("activated_articles", null, record);
row3.close();
else //If unlocked_articles is empty...
record.put("art0_unlock", 0);
record.put("art1_unlock", 0);
record.put("art2_unlock", 0);
record.put("art3_unlock", 0);
record.put("art4_unlock", 0);
Database.insert("unlocked_articles", null, record);
row2.close();
Database.close();
这是我的 AdminSQLiteOpenHelper 代码,值得知道 unlocked_articles
和 activated_articles
稍后添加,这就是我调用 onUpgrade
方法的原因:
package com.example.a14;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
public class AdminSQLiteOpenHelper extends SQLiteOpenHelper
public AdminSQLiteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version)
super(context, name, factory, version);
@Override
public void onCreate(SQLiteDatabase Database)
Database.execSQL("create table saved_data(victories int, lvls_unlocked int, score int)");
Database.execSQL("create table unlocked_articles(art0_unlock int, art1_unlock int, art2_unlock int, art3_unlock int, art4_unlock int)");
Database.execSQL("create table activated_articles(art0_activ int, art1_activ int, art2_activ int, art3_activ int, art4_activ int)");
@Override
public void onUpgrade(SQLiteDatabase Database, int i, int i1)
Database.execSQL("create table unlocked_articles(art0_unlock int, art1_unlock int, art2_unlock int, art3_unlock int, art4_unlock int)");
Database.execSQL("create table activated_articles(art0_activ int, art1_activ int, art2_activ int, art3_activ int, art4_activ int)");
onCreate(Database);
我不知道为什么这会导致应用崩溃,因为我没有发现错误。提前致谢。
【问题讨论】:
【参考方案1】:您遇到的一个问题是,如果/当您走到那一步时,您正在尝试更新不存在的列。
也就是说,您构建了一个 ContentValues(即 record),其中包含来自所有 3 个表的列,然后您将其用于更新所有 3 个表。您将得到一个未找到的列 SQLiteException,例如:-
android.database.sqlite.SQLiteException: no such column: art2_activ (code 1 SQLITE_ERROR): , while compiling: UPDATE saved_data SET art2_activ=?,score=?,art3_unlock=?,art4_unlock=?,art2_unlock=?,art3_activ=?,art1_activ=?,art0_unlock=?,art1_unlock=?,art4_activ=?,art0_activ=?
即在saved_data表中找不到art2_activ列(该列属于activated_articles表)。
因此,您需要 3 个单独的 ContentValue,每个都适合各自的表格。我还建议在结束时关闭游标,而不管遵循的路径。
这是一个调用 Buy
方法的工作示例(在添加一些数据之前先两次,然后在添加一些数据之后):-
public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AdminSQLiteOpenHelper db = new AdminSQLiteOpenHelper(this,"administration",null,3);
Buy(); // test empty (if first run since install)
/* NOTE insert methods added to the DB Helper to allow testing with some data */
db.insertSaved(10,1,0);
db.insertUnlocked(1,1,1,1,1);
db.insertActivated(1,1,1,1,1);
Buy(); // test with some data
public void Buy(/*View view <<<<<< COMMENTED OUT*/ )
//Database conection
AdminSQLiteOpenHelper admin = new AdminSQLiteOpenHelper(this, "administration", null, 3);
SQLiteDatabase Database= admin.getWritableDatabase();
//Database query
Cursor row = Database.rawQuery("select * from saved_data ", null);
Cursor row2 = Database.rawQuery("select * from unlocked_articles", null);
Cursor row3 = Database.rawQuery("select * from activated_articles", null);
ContentValues cv_score = new ContentValues();
ContentValues cv_unlock = new ContentValues();
ContentValues cv_activ = new ContentValues();
//final Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale); <<<<< COMMENTED OUT
if (row.moveToFirst()) //If db is not empty...
int score = row.getInt(2);
if(row2.moveToFirst())
int art0_unlock = row2.getInt(0); //One variable, one article
int art1_unlock = row2.getInt(1);
int art2_unlock = row2.getInt(2);
int art3_unlock = row2.getInt(3);
int art4_unlock = row2.getInt(4);
if(row3.moveToFirst())
int art0_activ = row3.getInt(0);
int art1_activ = row3.getInt(1);
int art2_activ = row3.getInt(2);
int art3_activ = row3.getInt(3);
int art4_activ = row3.getInt(4);
//if (art0.isSelected()) ... //Operations for the purchase are here, not the problem <<<<< COMMENTED OUT
//For saving data
cv_score.put("score",score);
cv_unlock.put("art0_unlock", art0_unlock);
cv_unlock.put("art1_unlock", art1_unlock);
cv_unlock.put("art2_unlock", art2_unlock);
cv_unlock.put("art3_unlock", art3_unlock);
cv_unlock.put("art4_unlock", art4_unlock);
cv_activ.put("art0_activ", art0_activ);
cv_activ.put("art1_activ", art1_activ);
cv_activ.put("art2_activ", art2_activ);
cv_activ.put("art3_activ", art3_activ);
cv_activ.put("art4_activ", art4_activ);
Database.update("saved_data", cv_score, null, null);
Database.update("unlocked_articles", cv_unlock, null, null);
Database.update("activated_articles", cv_activ, null, null);
else //If activated_articles is empty...
cv_activ.put("art0_activ", 0);
cv_activ.put("art1_activ", 0);
cv_activ.put("art2_activ", 0);
cv_activ.put("art3_activ", 0);
cv_activ.put("art4_activ", 0);
Database.insert("activated_articles", null, cv_activ);
else //If unlocked_articles is empty...
cv_unlock.put("art0_unlock", 0);
cv_unlock.put("art1_unlock", 0);
cv_unlock.put("art2_unlock", 0);
cv_unlock.put("art3_unlock", 0);
cv_unlock.put("art4_unlock", 0);
Database.insert("unlocked_articles", null, cv_unlock);
row.close();
row2.close();
row3.close();
Database.close();
注意部分代码已被注释掉
cv_score、cv_unlock 和 cv_activ 已使用 3 个 ContentValues 而不是单个 ContentValues record。。李>
【讨论】:
我实施了您建议的更改,但 logcat 给了我同样的错误。以上是关于sql 数据库中具有多个表的活动崩溃 - Android Studio的主要内容,如果未能解决你的问题,请参考以下文章