java.util.ConcurrentModificationException异常
刚刚转战Android,花了一个星期弄了个东西,
一直正常编译运行,买包烟回来就不能运行了,买烟之前都还好好的,
有备份,运行备份也是一样
求帮忙。
public class MainActivity2 extends AppCompatActivity {
DBAdapter dbAdapter;
TextView text;
FloatingActionButton fab;
@SuppressLint("MissingInflatedId")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main2);
dbAdapter=new DBAdapter(this);
text = findViewById(R.id.textView);
fab = findViewById(R.id.floatingActionButton);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {//点击悬浮按钮跳转到添加界面
Intent intent = new Intent(MainActivity2.this,MainActivity.class);
startActivity(intent);
}
});
List<MyFruit> mFruitList = new ArrayList<MyFruit>();
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
Cursor cursor=sqLiteDatabase.query(DB_TABLE,null,null,null,null,null,"_id DESC");
while (cursor.moveToNext()){//报错行
String _id = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
String khmc = cursor.getString(cursor.getColumnIndexOrThrow("khmc"));
String gcmc=cursor.getString(cursor.getColumnIndexOrThrow("gcmc"));
String sgbw=cursor.getString(cursor.getColumnIndexOrThrow("sgbw"));
String ysrq=cursor.getString(cursor.getColumnIndexOrThrow("ysrq"));
String qddj=cursor.getString(cursor.getColumnIndexOrThrow("qddj"));
String ksdj=cursor.getString(cursor.getColumnIndexOrThrow("ksdj"));
String bcfl=cursor.getString(cursor.getColumnIndexOrThrow("bcfl"));
String ljfl=cursor.getString(cursor.getColumnIndexOrThrow("ljfl"));
String ysch=cursor.getString(cursor.getColumnIndexOrThrow("ysch"));
String jsy=cursor.getString(cursor.getColumnIndexOrThrow("jsy"));
MyFruit bookStore=new MyFruit(_id,khmc,gcmc,sgbw,ysrq,qddj,ksdj,bcfl,ljfl,ysch,jsy);
mFruitList.add(bookStore);
}
text.setText("总车数:"+allCaseNum()+" "+"累计方量:"+(int) getsumdebt()+"M³");
cursor.close();
// 获取到 RecyclerView 实例
RecyclerView mRecyclerView = findViewById(R.id.test_rv);
// 创建 LinearLayoutManager 对象 ,即线性布局
LinearLayoutManager mManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mManager);
// 创建自定义的 Adapter 实例
MyFruitAdapter mAdapter = new MyFruitAdapter(mFruitList);
//进场动画
LayoutAnimationController controller = new LayoutAnimationController(AnimationUtils.loadAnimation(this,R.anim.my_anim));
mRecyclerView.setLayoutAnimation(controller);
// 设置适配器
mRecyclerView.setAdapter(mAdapter);
//itme 点击事件
mAdapter.setOnItemClick(new MyFruitAdapter.OnItemClick() {
@Override
public void onItemClick(int position) {
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity2.this);
dialog.setTitle("请选择操作:");
dialog.setIcon(R.drawable.icon);
dialog.setPositiveButton("修改",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(MainActivity2.this,Update.class);
MyFruit myFruit = mFruitList.get(position);
intent.putExtra("_id",myFruit.get_id());
intent.putExtra("khmc",myFruit.getKhmc());
intent.putExtra("gcmc",myFruit.getGcmc());
intent.putExtra("sgbw",myFruit.getSgbw());
intent.putExtra("ysrq",myFruit.getYsrq());
intent.putExtra("qddj",myFruit.getQddj());
intent.putExtra("ksdj",myFruit.getKsdj());
intent.putExtra("bcfl",myFruit.getBcfl());
intent.putExtra("ljfl",myFruit.getLjfl());
intent.putExtra("ysch",myFruit.getYsch());
intent.putExtra("jsy",myFruit.getJsy());
startActivity(intent);
}
});
dialog.setNeutralButton("删除",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
MyFruit myFruit = mFruitList.get(position);
String id1 = myFruit.get_id();
boolean shanchu = deleteUser(id1);
if (shanchu == true){
mFruitList.remove(position);
mAdapter.notifyItemRemoved(position);
mAdapter.notifyItemRangeChanged(position, mFruitList.size());
Toast.makeText(MainActivity2.this,"删除成功!",Toast.LENGTH_SHORT).show();
}else {Toast.makeText(MainActivity2.this,"删除失败!!!",Toast.LENGTH_SHORT).show();}
}
});
dialog.setNegativeButton("复制", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(MainActivity2.this,Copyone.class);
MyFruit myFruit = mFruitList.get(position);
intent.putExtra("_id",myFruit.get_id());
intent.putExtra("khmc",myFruit.getKhmc());
intent.putExtra("gcmc",myFruit.getGcmc());
intent.putExtra("sgbw",myFruit.getSgbw());
intent.putExtra("ysrq",myFruit.getYsrq());
intent.putExtra("qddj",myFruit.getQddj());
intent.putExtra("ksdj",myFruit.getKsdj());
intent.putExtra("bcfl",myFruit.getBcfl());
intent.putExtra("ljfl",myFruit.getLjfl());
intent.putExtra("ysch",myFruit.getYsch());
intent.putExtra("jsy",myFruit.getJsy());
startActivity(intent);
}
});
dialog.create();
dialog.show();
}
});
}
public double getsumdebt() {//统计总方量
int total = 0;
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
Cursor mCursor = sqLiteDatabase.rawQuery(" SELECT SUM(bcfl) FROM peopleinfo", null);
if (mCursor.moveToFirst())
{
total = mCursor.getInt(0);
}
while (mCursor.moveToNext());
return total;
}
/**
* 查询数据库中的总条数.
*/
public long allCaseNum( ){
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(MainActivity2.this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
Cursor cursor = sqLiteDatabase.rawQuery("select count(*) from "+DB_TABLE, null);
cursor.moveToFirst();
long count = cursor.getLong(0);
return count;
}
public boolean deleteUser(String ID){//删除方法
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
long id = sqLiteDatabase.delete(DB_TABLE,KEY_ID+"="+ID,null);
sqLiteDatabase.close();
return id>0?true:false;
}
public long update (String id ,ContentValues updateValues){
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
sqLiteDatabase.update(DB_TABLE,updateValues,KEY_ID+"="+id,null);
return 0;
}
}
参考GPT和自己的思路,该异常java.util.ConcurrentModificationException表示在迭代列表时,另一个线程修改了该列表,导致迭代器失效。在你的代码中没有明显的多线程,所以可能是因为在迭代mFruitList时在另一个地方修改了mFruitList。可能的原因是你在使用mFruitList的同时,在另一个线程中对mFruitList进行了修改。可以尝试在对mFruitList进行迭代的时候对其进行同步,以防止其他线程同时对其进行修改,如下所示:
List<MyFruit> mFruitList = new ArrayList<MyFruit>();
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
Cursor cursor=sqLiteDatabase.query(DB_TABLE,null,null,null,null,null,"_id DESC");
synchronized (mFruitList) { // 同步块
while (cursor.moveToNext()){
String _id = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
String khmc = cursor.getString(cursor.getColumnIndexOrThrow("khmc"));
String gcmc=cursor.getString(cursor.getColumnIndexOrThrow("gcmc"));
String sgbw=cursor.getString(cursor.getColumnIndexOrThrow("sgbw"));
String ysrq=cursor.getString(cursor.getColumnIndexOrThrow("ysrq"));
String qddj=cursor.getString(cursor.getColumnIndexOrThrow("qddj"));
String ksdj=cursor.getString(cursor.getColumnIndexOrThrow("ksdj"));
String bcfl=cursor.getString(cursor.getColumnIndexOrThrow("bcfl"));
String ljfl=cursor.getString(cursor.getColumnIndexOrThrow("ljfl"));
String ysch=cursor.getString(cursor.getColumnIndexOrThrow("ysch"));
String jsy=cursor.getString(cursor.getColumnIndexOrThrow("jsy"));
MyFruit bookStore=new MyFruit(_id,khmc,gcmc,sgbw,ysrq,qddj,ksdj,bcfl,ljfl,ysch,jsy);
mFruitList.add(bookStore);
}
}
cursor.close();
另外,也可以尝试使用CopyOnWriteArrayList类代替ArrayList类,CopyOnWriteArrayList类是一个线程安全的ArrayList,当有修改操作时,它会创建一个新的副本来进行修改,而不会影响到迭代操作,从而避免了ConcurrentModificationException异常。
望采纳,建议修改while(cursor.moveToNext())
while(cursor.hasNext()){
cursor.moveToNext();
}
DBAdapter
package com.example.my;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
public static final String DB_NAME="People.db";
static final String DB_TABLE="peopleinfo";
private static final int DB_VERSION=1;
public static final String KEY_ID="_id";
public static final String KEY_KHMC="khmc";
public static final String KEY_GCMC="gcmc";
public static final String KEY_SGBW="sgbw";
public static final String KEY_YSRQ="ysrq";
public static final String KEY_QDDJ="qddj";
public static final String KEY_KSDJ="ksdj";
public static final String KEY_BCFL="bcfl";
public static final String KEY_LJFL="ljfl";
public static final String KEY_YSCH="ysch";
public static final String KEY_JSY="jsy";
private SQLiteDatabase db;
private final Context context;
private DBOpenHelper dbOpenHelper;
private static final String DB_CREATE="create table "+
DB_TABLE+" ("+KEY_ID+" integer primary key autoincrement, "+
KEY_KHMC+" text not null, "+KEY_GCMC+" text not null, "+KEY_SGBW+
" text not null, "+KEY_YSRQ+" text not null, "+KEY_QDDJ+" text not null, "+KEY_KSDJ+" text not null, " +
""+KEY_BCFL+" text not null, "+KEY_LJFL+" text not null, "+KEY_YSCH+" text not null, "+KEY_JSY+" text not null);";
public DBAdapter(Context _context){
context=_context;
}
public void close(){
if(db!=null){
db.close();
db=null;
}
}
public void open()throws SQLiteException{
dbOpenHelper=new DBOpenHelper(context,DB_NAME,null,DB_VERSION);
try{
db=dbOpenHelper.getWritableDatabase();
}catch(SQLiteException ex){
db=dbOpenHelper.getReadableDatabase();
}
close();
}
private static class DBOpenHelper extends SQLiteOpenHelper{
public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,int version){
super(context,name,factory,version);
}
private static final String DB_CREATE="create table "+
DB_TABLE+" ("+KEY_ID+" integer primary key autoincrement, "+
KEY_KHMC+" text not null, "+KEY_GCMC+" text not null, "+KEY_SGBW+
" text not null, "+KEY_YSRQ+" text not null, "+KEY_QDDJ+" text not null, "+KEY_KSDJ+" text not null, " +
""+KEY_BCFL+" text not null, "+KEY_LJFL+" text not null, "+KEY_YSCH+" text not null, "+KEY_JSY+" text not null);";
@Override
public void onCreate(SQLiteDatabase _db){
_db.execSQL(DB_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase _db,int _oldVersion,int _newVersion){
_db.execSQL("DROP TABLE IF EXISTS "+DB_TABLE);
onCreate(_db);
}
};
/*
public long insert(People people){}
public long deleteAllData(){ }
public long deleteOneData(long id){ }
public People[] queryAllData(){ }
public People[] queryOneData(){ }
public long updateOneData(long id,People people){ }
private People[] ConvertTopeople(Cursor cursor){ }
*/
public long insert(People people){
ContentValues newValues=new ContentValues();
newValues.put(KEY_KHMC,people.khmc);
newValues.put(KEY_GCMC,people.gcmc);
newValues.put(KEY_SGBW,people.sgbw);
newValues.put(KEY_YSRQ,people.ysrq);
newValues.put(KEY_QDDJ,people.qddj);
newValues.put(KEY_KSDJ,people.ksdj);
newValues.put(KEY_BCFL,people.bcfl);
newValues.put(KEY_LJFL,people.ljfl);
newValues.put(KEY_YSCH,people.ysch);
newValues.put(KEY_JSY,people.jsy);
return db.insert(DB_TABLE,null,newValues);
}
public People[] getOneData(long id){
Cursor results=db.query(DB_TABLE,new String[]{KEY_ID,KEY_KHMC,KEY_GCMC,KEY_SGBW,KEY_YSRQ,KEY_QDDJ,KEY_KSDJ,KEY_BCFL,KEY_LJFL,KEY_YSCH,KEY_JSY},
KEY_ID+"="+id,null,null,null,null);
return ConvertToPeople(results);
}
public People[] getAllData(){
Cursor results=db.query(DB_TABLE,new String[]{KEY_ID,KEY_KHMC,KEY_GCMC,KEY_SGBW,KEY_YSRQ,KEY_QDDJ,KEY_KSDJ,KEY_BCFL,KEY_LJFL,KEY_YSCH,KEY_JSY},
null,null,null,null,null);
return ConvertToPeople(results);
}
@SuppressLint("Range")
private People[] ConvertToPeople(Cursor cursor){//返回数据库全部数据
int resultCounts=cursor.getCount();
cursor.moveToFirst();
People[] peoples=new People[resultCounts];
for(int i=0;i<resultCounts;i++){
peoples[i]=new People();
peoples[i].ID=cursor.getInt(0);
peoples[i].khmc=cursor.getString(cursor.getColumnIndex(KEY_KHMC));
peoples[i].gcmc=cursor.getString(cursor.getColumnIndex(KEY_GCMC));
peoples[i].sgbw=cursor.getString(cursor.getColumnIndex(KEY_SGBW));
peoples[i].ysrq=cursor.getString(cursor.getColumnIndex(KEY_YSRQ));
peoples[i].qddj=cursor.getString(cursor.getColumnIndex(KEY_QDDJ));
peoples[i].ksdj=cursor.getString(cursor.getColumnIndex(KEY_KSDJ));
peoples[i].bcfl=cursor.getString(cursor.getColumnIndex(KEY_BCFL));
peoples[i].ljfl=cursor.getString(cursor.getColumnIndex(KEY_LJFL));
peoples[i].ysch=cursor.getString(cursor.getColumnIndex(KEY_YSCH));
peoples[i].jsy=cursor.getString(cursor.getColumnIndex(KEY_JSY));
cursor.moveToNext();
}
return peoples;
}
public long deleteAllData(){
db.execSQL("DROP TABLE IF EXISTS "+DB_TABLE);
db.execSQL(DB_CREATE);
return 0;
}
public long deleteOneData(long id){
return db.delete(DB_TABLE,KEY_ID+"="+id,null);
}
public long updateOneData(long id,People people){
ContentValues updateValues=new ContentValues();
updateValues.put(KEY_KHMC,people.khmc);
updateValues.put(KEY_GCMC,people.gcmc);
updateValues.put(KEY_SGBW,people.sgbw);
updateValues.put(KEY_YSRQ,people.ysrq);
updateValues.put(KEY_QDDJ,people.qddj);
updateValues.put(KEY_KSDJ,people.ksdj);
updateValues.put(KEY_BCFL,people.bcfl);
updateValues.put(KEY_LJFL,people.ljfl);
updateValues.put(KEY_YSCH,people.ysch);
updateValues.put(KEY_JSY,people.jsy);
return db.update(DB_TABLE,updateValues,KEY_ID+"="+id,null);
}
}
该回答内容部分引用GPT,GPT_Pro更好的解决问题
Java.util.ConcurrentModificationException异常是因为并发修改异常,也就是说你在同一时间内对同一个集合进行添加或删除操作,这里面的操作可能是你的程序在运行中,也可能是多线程情况下的操作,只要是在同一时间出现的数据修改和添加的操作都会出现这个异常。
具体解决方法有以下几种:
将集合保存到一个对象中,然后在进行修改前进行判断,如果对象中有元素,就不再修改。
使用同步代码块,即在操作集合时使用synchronized关键字,从而防止多线程中出现并发修改异常。
使用java.util.concurrent包中的集合工具类来实现,如使用CopyOnWriteArrayList或者CopyOnWriteArraySet等集合工具类。
使用Collections.synchronizedList(List<>)将集合转换成一个同步的集合,从而避免多线程中出现并发修改异常。
使用java.util.concurrent.locks中的ReentrantLock锁来实现:
ReentrantLock lock = new ReentrantLock(); // 定义一个ReentrantLock对象
lock.lock(); // 获取锁
try{
//要执行的代码
}finally{
lock.unlock(); // 释放锁
}
如果回答有帮助,望采纳。
这个错误java.util.ConcurrentModificationException表示在遍历集合(如ArrayList)时,同时尝试修改它。在这种情况下,你正在遍历一个ArrayList,并在其中添加元素。由于这个原因,就会抛出ConcurrentModificationException异常。修改后的代码如下:
List<MyFruit> mFruitList = new ArrayList<MyFruit>();
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
Cursor cursor=sqLiteDatabase.query(DB_TABLE,null,null,null,null,null,"_id DESC");
if (cursor != null && cursor.moveToFirst()) {
do {
String _id = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
String khmc = cursor.getString(cursor.getColumnIndexOrThrow("khmc"));
String gcmc=cursor.getString(cursor.getColumnIndexOrThrow("gcmc"));
String sgbw=cursor.getString(cursor.getColumnIndexOrThrow("sgbw"));
String ysrq=cursor.getString(cursor.getColumnIndexOrThrow("ysrq"));
String qddj=cursor.getString(cursor.getColumnIndexOrThrow("qddj"));
String ksdj=cursor.getString(cursor.getColumnIndexOrThrow("ksdj"));
String bcfl=cursor.getString(cursor.getColumnIndexOrThrow("bcfl"));
String ljfl=cursor.getString(cursor.getColumnIndexOrThrow("ljfl"));
String ysch=cursor.getString(cursor.getColumnIndexOrThrow("ysch"));
String jsy=cursor.getString(cursor.getColumnIndexOrThrow("jsy"));
MyFruit bookStore=new MyFruit(_id,khmc,gcmc,sgbw,ysrq,qddj,ksdj,bcfl,ljfl,ysch,jsy);
mFruitList.add(bookStore);
} while (cursor.moveToNext());
}
if(cursor != null) {
cursor.close();
}
如有帮助,望采纳。
可以贴下MainActivity2 这个类。
题主给出的异常类型是ConcurrentModificationException,字面意思就是多线程对同一个内容进行操作导致。
这个异常通常是由于在迭代集合的同时修改了集合导致的。在您的代码中,可能是由于
mFruitList
和sqLiteDatabase
同时在不同的线程中进行了修改,从而导致此异常。您可以尝试在迭代时使用Iterator
并在添加或删除元素时使用Iterator.remove()
方法,这将确保集合在迭代过程中不会被修改。
您可以尝试修改代码如下:
List<MyFruit> mFruitList = new ArrayList<MyFruit>();
MySQLiteOpenHelper mySQLiteOpenHelper=new MySQLiteOpenHelper(this,DB_NAME,null,1);
SQLiteDatabase sqLiteDatabase=mySQLiteOpenHelper.getWritableDatabase();
Cursor cursor=sqLiteDatabase.query(DB_TABLE,null,null,null,null,null,"_id DESC");
Iterator<Cursor> iterator = cursor.iterator();
while (iterator.hasNext()) {
Cursor currentCursor = iterator.next();
String _id = currentCursor.getString(currentCursor.getColumnIndexOrThrow("_id"));
String khmc = currentCursor.getString(currentCursor.getColumnIndexOrThrow("khmc"));
String gcmc = currentCursor.getString(currentCursor.getColumnIndexOrThrow("gcmc"));
String sgbw = currentCursor.getString(currentCursor.getColumnIndexOrThrow("sgbw"));
String ysrq = currentCursor.getString(currentCursor.getColumnIndexOrThrow("ysrq"));
String qddj = currentCursor.getString(currentCursor.getColumnIndexOrThrow("qddj"));
String ksdj = currentCursor.getString(currentCursor.getColumnIndexOrThrow("ksdj"));
String bcfl = currentCursor.getString(currentCursor.getColumnIndexOrThrow("bcfl"));
String ljfl = currentCursor.getString(currentCursor.getColumnIndexOrThrow("ljfl"));
String ysch = currentCursor.getString(currentCursor.getColumnIndexOrThrow("ysch"));
String jsy = currentCursor.getString(currentCursor.getColumnIndexOrThrow("jsy"));
MyFruit bookStore = new MyFruit(_id, khmc, gcmc, sgbw, ysrq, qddj, ksdj, bcfl, ljfl, ysch, jsy);
mFruitList.add(bookStore);
}
cursor.close();
希望能帮到您解决问题。
该回答基于ChatGPT与个人思路编写:
要修复此错误,您应该在尝试移动到下一个位置之前检查游标是否为空。你可以在while循环之前添加一个if语句:if (cursor != null) {while (cursor. movetonext){…)此外,您应该检查您试图访问的列是否存在于数据库表中。
建议使用判空并检查数据库是否存在空值,使用完cursor后记得关闭游标以避免内存泄漏。
1.数据库的操作,请封装到单独的单例类中,然后所有的操作,放置于子线程中进行
2.while语句改一下while(cursor.moveToNext())