2015-05-14 270 views
0

我試圖從我的數據庫中獲取數據,並且檢查了表中有數據。從SQlite數據庫獲取對象?

即時得到這個錯誤:

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()以某種方式產生這個錯誤。

回答

3

忘記了c.moveToNext();。這意味着您將一次又一次從數據庫讀取第一行,並且您將一次又一次創建相同的Product,並將其永久添加到您的列表中,並且您將收到內存不足錯誤。像這樣做:

[...] 

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(); 
}