2011-12-09 82 views
0

嗯,我有關於SQLite數據庫的問題。我使用列表視圖創建了一個活動,以便在單擊某個項目時顯示下一個活動。這是應用程序啓動時首先顯示的主要活動。該活動是這樣的,在初始化期間它將值插入到表中。數據庫中的表具有包含主鍵和唯一字段的字段。我已經聲明這些字段是唯一的,以便重複字段不會在下一行中添加。只是應該避免在新行中插入相同的值。 值的初始化和插入在第一個活動本身的onCreate中聲明。但是在這裏出現的問題是,當這個應用程序關閉並再次打開時,它會在Logcat中寫入錯誤消息「在ButterflyDB中插入值時出錯」。我知道這個問題出現bcoz已經有一個數據庫,並且這些字段被聲明爲唯一的。當它在第一個活動中調用插入函數時,也需要花費大量的時間來顯示活動。經過一段時間的延遲後,第一個屏幕出現bcoz應用程序將在每次出現第一個屏幕時將值插入到數據庫中。如何處理數據庫的正確方法android

我給這家代碼如下:

package com.myambitionconsultants.butterflyworld; 

import android.app.ListActivity; 
import android.content.ContentValues; 
import android.content.Intent; 
import android.database.Cursor; 
import android.database.SQLException; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.TextView; 

public class ButterflyWorldActivity extends ListActivity { 
    private static final String TAG = ButterflyWorldActivity.class.getSimpleName(); 
    /** 
    * Declare the variables and objects. 
    * ButterflyDBAdapter - To initialize the DB, create the tables and store the values in it. 
    * ImageIDStorage - To store the Image drawable IDs into the table. 
    * String[], int[] - To access the arrays declared in the data.xml file. 
    * String - SQL statements to run when this activity is displayed. 
    * Cursor - To access the records in the row of the table to display. 
    */ 
    ButterflyDBAdapter dbAdapter; 
    ImageIDStorage imgIDStorage; 
    ButterflyDetailsStorage detailsStorage; 
    String[] levels, butterfly_common_names, butterfly_scientific_names, image_path, cat_id; 
    int [] drawableID; 
    int [] butterfly_id; 
    String sql_butterfly_cat, sql_drawable_id; 
    Cursor cur; 




    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     /** 
     * Initialize the declared variables. 
     * dbAdapter - Initialize with ButterflyDBAdapter object. 
     * imgIDStorage - Initialize with ImageIDStorage object. 
     * 
     * levels, butterfly_common_names, butterfly_scientific_names, image_path, butterfly_id, cat_id 
     * - Use the getStringArray() method to load each and every value from the XML. 
     */ 

     dbAdapter = new ButterflyDBAdapter(this); 
     imgIDStorage = new ImageIDStorage(this); 
     detailsStorage = new ButterflyDetailsStorage(this); 
     dbAdapter.createTable(); 
     levels = getResources().getStringArray(R.array.butterfly_categories); 
     butterfly_common_names = getResources().getStringArray(R.array.butterfly_common_names); 
     butterfly_scientific_names = getResources().getStringArray(R.array.butterfly_scientific_names); 
     //image_path = getResources().getStringArray(R.array.image_path); 
     butterfly_id = getResources().getIntArray(R.array.butterfly_id); 
     cat_id = getResources().getStringArray(R.array.category_id); 
     //drawables = getResources().getStringArray(R.array.drawable_array); 

     /** 
     * Method Calls. 
     * Insert the Butterfly Categories, Butterflies, ImageIDs in the database. 
     */ 
     insertButterflyCategory(); 
     insertButterfly(); 
     imgIDStorage.insertImageID_1(); 
     imgIDStorage.insertImageID_2(); 
     detailsStorage.insertButterflyDetails(); 
     /** 
     * SQL statement to select the Category Name from the ButterflyCategory Table. 
     * Initialize the cursor to execute the query from the table. 
     */ 
     sql_butterfly_cat = "Select " + ButterflyDBAdapter.COL_CATEGORY_NAME + " from " + ButterflyDBAdapter.BUTTERFLY_CATEGORY; 
     cur = dbAdapter.getSQLiteDB().rawQuery(sql_butterfly_cat, null); 


     /** 
     * After retrieving the rows from the cursor, store the category name values in the array. 
     * Move the cursor to the first. 
     * Till the last row value in the table, keep on adding the category names in the array. 
     */ 

     //After retrieving the rows from the cursor, store the category name values in the array. 
     String[] category = new String[cur.getCount()]; 
     Log.i(TAG, "Count: " + cur.getCount()); 

     cur.moveToFirst(); //Move the cursor to the first row. 
     for(int i = 0; i < cur.getCount(); i++){ 
      //Till the last row value in the table, keep on adding the category names in the array. 
      category[i] =cur.getString(cur.getColumnIndex(ButterflyDBAdapter.COL_CATEGORY_NAME)); 
      //Move the cursor to the next row 
      cur.moveToNext(); 
     } 

     /** 
     * Use the setListAdapter() method to display the category names in the list. 
     */ 
     setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, category)); 

     /** 
     * Use the getListView() method. 
     */ 
     ListView lv = getListView(); 
     lv.setTextFilterEnabled(true); 

     /** 
     * Manage the cursor 
     */ 
     startManagingCursor(cur); 

     /** 
     * Determine which category was clicked in the list. 
     * Pass the category name as extra in the bundle. 
     * Display the next activity with the values passed through the bundle. 
     */ 
     lv.setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, 
      int position, long id) { 

      String category_name = ((TextView) view).getText().toString(); 
      Intent i = new Intent(ButterflyWorldActivity.this, ShowCategory.class); 
      //Intent i2 = new Intent(ButterflyWorldActivity.this, .class); 
      i.putExtra("category_name", category_name); 
      Bundle bundle = new Bundle(); 

      switch(position){ 
      case 0: 
       bundle.putString("category_name", category_name); 
       //bundle.putInt("drawable1", R.drawable.tailed_jay_1); 
       //bundle.putInt("drawable2", R.drawable.blue_bottle_1); 
       //bundle.putInt("drawable3", R.drawable.common_raven_1); 
       i.putExtras(bundle); 
       startActivity(i); 
       break; 
      case 1: 
       bundle.putString("category_name", category_name); 
       //bundle.putInt("drawable1", R.drawable.common_wanderer_1); 
       //bundle.putInt("drawable2", R.drawable.common_jezabel_1); 
       //bundle.putInt("drawable3", R.drawable.psyche_1); 
       i.putExtras(bundle); 
       startActivity(i); 
       break; 
      case 2: 
       bundle.putString("category_name", category_name); 
       //bundle.putInt("drawable1", R.drawable.common_silverline_1); 
       //bundle.putInt("drawable2", R.drawable.grass_jewel_1); 
       //bundle.putInt("drawable3", R.drawable.monkey_puzzle_1); 
       i.putExtras(bundle); 
       startActivity(i); 
       break; 
      case 3: 
       bundle.putString("category_name", category_name); 
       //bundle.putInt("drawable1", R.drawable.leopard_1); 
       //bundle.putInt("drawable1", R.drawable.common_silverline_1); 
       //bundle.putInt("drawable2", R.drawable.peacock_pansy_1); 
       //bundle.putInt("drawable3", R.drawable.blue_oakleaf_1); 
       i.putExtras(bundle); 
       startActivity(i); 
       break; 
      case 4: 
       bundle.putString("category_name", category_name); 
       //bundle.putInt("drawable1", R.drawable.chestnut_bob_1); 
       //bundle.putInt("drawable2", R.drawable.golden_angle_1); 
       //bundle.putInt("drawable3", R.drawable.grass_demon_1); 
       //bundle.putInt("drawable3", R.drawable.psyche_1); 
       i.putExtras(bundle); 
       startActivity(i); 
       break; 
      }   
     } 

     }); 

    } 


    /** 
    * Insert the butterfly category names into the database. 
    * The number of values in the levels[] determines the number of 
    * rows to be put in the ButterflyCategory table. 
    */ 
    public void insertButterflyCategory(){ 

     for(int i = 0; i<levels.length;i++){ 
      ContentValues cv = new ContentValues(); 
      //cv.put(ButterflyDBAdapter.COL_CATEGORY_ID, i+1); 
      cv.put(ButterflyDBAdapter.COL_CATEGORY_NAME, levels[i]); 

      try{ 
       dbAdapter.getSQLiteDB().insert(ButterflyDBAdapter.BUTTERFLY_CATEGORY, null, cv); 
       //dbAdapter.getSQLiteDB().insertWithOnConflict(ButterflyDBAdapter.BUTTERFLY_CATEGORY, null, cv,SQLiteDatabase.CONFLICT_IGNORE); 
       //dbAdapter.getSQLiteDB().insertOrThrow(ButterflyDBAdapter.BUTTERFLY_CATEGORY, null, cv); 
      }catch(SQLException e) { 
       e.printStackTrace(); 
      } 
     } 
     Log.i(TAG, "Category Values inserted in " + ButterflyDBAdapter.BUTTERFLY_CATEGORY); 
    } 
    /** 
    * Insert the butterfly details such as category id, common name, scientific name and detailed info into the database. 
    * The number of values in the butterfly_common_names[] determines the number of 
    * rows to be put in the Butterfly table. 
    */ 
    public void insertButterfly(){ 
     for(int i = 0; i<butterfly_common_names.length;i++){ 
      ContentValues cv = new ContentValues(); 

      cv.put(ButterflyDBAdapter.COL_BUTTERFLY_COMMON_NAME, butterfly_common_names[i]); 
      cv.put(ButterflyDBAdapter.COL_CAT_ID, Integer.parseInt(cat_id[i])); 
      cv.put(ButterflyDBAdapter.COL_BUTTERFLY_SCIENTIFIC_NAME, butterfly_scientific_names[i]); 
      try{ 
       dbAdapter.getSQLiteDB().insert(ButterflyDBAdapter.BUTTERFLY, null, cv); 
       //dbAdapter.getSQLiteDB().insertWithOnConflict(ButterflyDBAdapter.BUTTERFLY_CATEGORY, null, cv,SQLiteDatabase.CONFLICT_IGNORE); 
       //dbAdapter.getSQLiteDB().insertOrThrow(ButterflyDBAdapter.BUTTERFLY_CATEGORY, null, cv); 
      }catch(SQLException e) { 
       e.printStackTrace(); 
      } 
     } 
     Log.i(TAG, "Butterfly Values inserted in " + ButterflyDBAdapter.BUTTERFLY); 
    } 

    /** 
    * Close the database and cursor on finish of activity. 
    */ 
    @Override 
    protected void onDestroy() { 
     // TODO Auto-generated method stub 
     super.onDestroy(); 
     dbAdapter.getSQLiteDB().close(); 
     cur.close(); 
     imgIDStorage.closeDB(); 
     detailsStorage.closeDB(); 
     //super.onDestroy(); 
    } 

    /** 
    * Close the database and cursor on finish of activity. 
    */ 
    @Override 
    protected void onPause() { 
     // TOD Auto-generated method stub 
     super.onPause(); 
     dbAdapter.getSQLiteDB().close(); 
     cur.close(); 
     imgIDStorage.closeDB(); 
     detailsStorage.closeDB(); 
     //super.onPause(); 
    } 
} 

的DDMS此如下:

12-09 11:38:53.299: E/Database(1375): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed 
12-09 11:38:53.299: E/Database(1375): at android.database.sqlite.SQLiteStatement.native_execute(Native Method) 
12-09 11:38:53.299: E/Database(1375): at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:55) 
12-09 11:38:53.299: E/Database(1375): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1549) 
12-09 11:38:53.299: E/Database(1375): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1410) 
12-09 11:38:53.299: E/Database(1375): at com.myambitionconsultants.butterflyworld.ButterflyWorldActivity.insertButterflyCategory(ButterflyWorldActivity.java:204) 
12-09 11:38:53.299: E/Database(1375): at com.myambitionconsultants.butterflyworld.ButterflyWorldActivity.onCreate(ButterflyWorldActivity.java:78) 
12-09 11:38:53.299: E/Database(1375): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
12-09 11:38:53.299: E/Database(1375): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
12-09 11:38:53.299: E/Database(1375): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
12-09 11:38:53.299: E/Database(1375): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
12-09 11:38:53.299: E/Database(1375): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
12-09 11:38:53.299: E/Database(1375): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-09 11:38:53.299: E/Database(1375): at android.os.Looper.loop(Looper.java:123) 
12-09 11:38:53.299: E/Database(1375): at android.app.ActivityThread.main(ActivityThread.java:4627) 
12-09 11:38:53.299: E/Database(1375): at java.lang.reflect.Method.invokeNative(Native Method) 
12-09 11:38:53.299: E/Database(1375): at java.lang.reflect.Method.invoke(Method.java:521) 
12-09 11:38:53.299: E/Database(1375): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
12-09 11:38:53.299: E/Database(1375): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
12-09 11:38:53.299: E/Database(1375): at dalvik.system.NativeStart.main(Native Method) 
12-09 11:38:53.369: E/Database(1375): Error inserting CategoryName=Pieridae 
12-09 11:38:53.369: E/Database(1375): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed 
12-09 11:38:53.369: E/Database(1375): at android.database.sqlite.SQLiteStatement.native_execute(Native Method) 
12-09 11:38:53.369: E/Database(1375): at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:55) 
12-09 11:38:53.369: E/Database(1375): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1549) 
12-09 11:38:53.369: E/Database(1375): at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1410) 
12-09 11:38:53.369: E/Database(1375): at com.myambitionconsultants.butterflyworld.ButterflyWorldActivity.insertButterflyCategory(ButterflyWorldActivity.java:204) 
12-09 11:38:53.369: E/Database(1375): at com.myambitionconsultants.butterflyworld.ButterflyWorldActivity.onCreate(ButterflyWorldActivity.java:78) 
12-09 11:38:53.369: E/Database(1375): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
12-09 11:38:53.369: E/Database(1375): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
12-09 11:38:53.369: E/Database(1375): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
12-09 11:38:53.369: E/Database(1375): at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
12-09 11:38:53.369: E/Database(1375): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
12-09 11:38:53.369: E/Database(1375): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-09 11:38:53.369: E/Database(1375): at android.os.Looper.loop(Looper.java:123) 
12-09 11:38:53.369: E/Database(1375): at android.app.ActivityThread.main(ActivityThread.java:4627) 
12-09 11:38:53.369: E/Database(1375): at java.lang.reflect.Method.invokeNative(Native Method) 
12-09 11:38:53.369: E/Database(1375): at java.lang.reflect.Method.invoke(Method.java:521) 
12-09 11:38:53.369: E/Database(1375): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
12-09 11:38:53.369: E/Database(1375): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
12-09 11:38:53.369: E/Database(1375): at dalvik.system.NativeStart.main(Native Method) 

如何處理這種類型的錯誤?

回答

0

您應該將所有填充數據庫的代碼(用於將數據從資源傳輸到數據庫的所有方法)移動到實際的ButterflyDBAdapter中。在適配器的onCreate()方法中,您可以檢查數據庫是否已經存在,如果不存在,請使用您的默認數據組填充它。然後你可以公開一些插入和從數據庫中檢索數據的方法。在你的ButterflyWorldActivity中,你只需要通過這些方法與數據庫進行交互。

0

我不明白你爲什麼要在Activity.onCreate()中創建和填充數據庫。這隻需要在第一次啓動時完成一次。

在你的ButterflyDBAdapter中,你有擴展SQLiteOpenHelper的類嗎?如果是這樣,你應該在SQLiteOpenHelper的onCreate()處理程序中創建並填充數據庫。你可以發佈ButterflyDBAdapter代碼嗎?

1

在您的日誌上查看時,錯誤是「約束失敗」,這意味着您嘗試將空值插入到非空列或具有主鍵的列中。

否則您嘗試將重複值插入到具有主鍵或唯一鍵的列中。

然後您可以在插入值之前刪除表格。由於這些值是在首次啓動應用程序時插入的,並且從下次開始,應用程序將嘗試插入相同的值。

相關問題