我试图从我的数据库中获取数据,并且我已检查表中是否有数据。
我收到此错误:
Process: com.example.olev.shoppinglist, PID: 4636
java.lang.OutOfMemoryError: Failed to allocate a 13571692 byte allocation with 3197016 free bytes and 3MB until OOM
at java.util.ArrayList.add(ArrayList.java:118)
at com.example.olev.shoppinglist.DBHandler.getProductsFromDb(DBHandler.java:63)
at com.example.olev.shoppinglist.MainActivity.getProductsFromDb(MainActivity.java:66)
at com.example.olev.shoppinglist.MainActivity.onCreate(MainActivity.java:39)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
MY DBHandler:
public void onCreate(SQLiteDatabase db) {
String query= "CREATE TABLE " + TABLE_PRODUCTS + " ("+
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
COLUMN_PRODUCTNAME + " TEXT," +
COLUMN_ISCHECKED + " BOOLEAN" +
");";
db.execSQL(query);
}
public ArrayList<Product> getProductsFromDb(){
ArrayList<Product> products= new ArrayList<>();
SQLiteDatabase db=getWritableDatabase();
String query= "SELECT * FROM "+ TABLE_PRODUCTS +";";
Cursor c= db.rawQuery(query,null);
c.moveToFirst();
while (!c.isAfterLast()){
if(c.getString(c.getColumnIndex("productname"))!=null){
Product product=new Product(Integer.parseInt(c.getString(c.getColumnIndex(COLUMN_ID))),COLUMN_PRODUCTNAME,Boolean.valueOf(c.getString(c.getColumnIndex(COLUMN_ISCHECKED))));
products.add(product);
}
}
db.close();
return products;
}
最后我的主要:
ArrayAdapter<Product> adapter;
ArrayList<Product> productnames=new ArrayList<>();
DBHandler dbhandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView productList=(ListView)findViewById(android.R.id.list);
dbhandler=new DBHandler(this,null,null,1);
getProductsFromDb();
adapter= new CustomAdapter(this,productnames);
productList.setAdapter(adapter);
}
public void getProductsFromDb() {
ArrayList<Product> products=dbhandler.getProductsFromDb();
productnames.addAll(products);
adapter.notifyDataSetChanged();
}
总而言之,getProductsFromDb()以某种方式产生了这个错误。
答案 0 :(得分:3)
你忘记了c.moveToNext();
。这意味着您将一次又一次地从数据库中读取第一行,并且您将一次又一次地创建相同的Product
,并一次又一次地将它添加到您的列表中,并且您将获得Out Of Memory错误。这样做:
[...]
while (!c.isAfterLast()){
if(c.getString(c.getColumnIndex("productname"))!=null) {
Product product=new Product(Integer.parseInt(c.getString(c.getColumnIndex(COLUMN_ID))),COLUMN_PRODUCTNAME,Boolean.valueOf(c.getString(c.getColumnIndex(COLUMN_ISCHECKED))));
products.add(product);
}
c.moveToNext();
}