在sqlite datatable中插入值时出现空指针异常 - Android

时间:2012-07-25 08:35:26

标签: android sqlite

我一直在尝试开发一个应用程序,在其中我在数据库中添加项目的arraylist并在listview中显示它们,但是在尝试插入数据库时​​我得到空指针异常。 这是日志

    07-25 13:41:22.826: E/DB ERROR(306): java.lang.NullPointerException
07-25 13:41:22.826: W/System.err(306): java.lang.NullPointerException
07-25 13:41:22.936: W/System.err(306):  at com.demo.itemscanner.ItemScannerDatabaseManager.addRow(ItemScannerDatabaseManager.java:91)
07-25 13:41:22.936: W/System.err(306):  at com.demo.itemscanner.ItemScannerDatabaseManager$CustomSQLiteOpenHelper.onCreate(ItemScannerDatabaseManager.java:64)
07-25 13:41:22.936: W/System.err(306):  at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:106)
07-25 13:41:22.936: W/System.err(306):  at com.demo.itemscanner.ItemScannerDatabaseManager.<init>(ItemScannerDatabaseManager.java:38)
07-25 13:41:22.936: W/System.err(306):  at com.demo.itemscanner.ItemScannerActivity.onCreate(ItemScannerActivity.java:33)
07-25 13:41:22.936: W/System.err(306):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-25 13:41:22.936: W/System.err(306):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
07-25 13:41:22.936: W/System.err(306):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-25 13:41:22.946: W/System.err(306):  at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-25 13:41:22.946: W/System.err(306):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-25 13:41:22.946: W/System.err(306):  at android.os.Handler.dispatchMessage(Handler.java:99)
07-25 13:41:22.946: W/System.err(306):  at android.os.Looper.loop(Looper.java:123)
07-25 13:41:22.946: W/System.err(306):  at android.app.ActivityThread.main(ActivityThread.java:4627)
07-25 13:41:22.946: W/System.err(306):  at java.lang.reflect.Method.invokeNative(Native Method)
07-25 13:41:22.946: W/System.err(306):  at java.lang.reflect.Method.invoke(Method.java:521)
07-25 13:41:22.946: W/System.err(306):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-25 13:41:22.946: W/System.err(306):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-25 13:41:22.946: W/System.err(306):  at dalvik.system.NativeStart.main(Native Method)

以下是与之关联的代码:

ItemScannerDatabaseManager.java

package com.demo.itemscanner;

import java.util.ArrayList;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class ItemScannerDatabaseManager {

    // the Activity or Application that is creating an object from this class.
    Context context;

    // a reference to the database used by this application/object
    private SQLiteDatabase db;

    // These constants are specific to the database. They should be
    // changed to suit your needs.
    private final String DB_NAME = "item_scanner";
    private final int DB_VERSION = 1;
    // These constants are specific to the database table. They should be
    // changed to suit your needs.
    private final String TABLE_NAME = "item_table";
    private final String ITEM_ID = "id";
    private final String ITEM_NAME = "item_name";
    private final String ITEM_PRICE = "item_price";
    private final String CURRENT_STOCK = "current_stock";
    private final String IMAGE = "image";

    public ItemScannerDatabaseManager(Context context) {
        this.context = context;
        // create or open the database
        CustomSQLiteOpenHelper helper = new CustomSQLiteOpenHelper(context);
        this.db = helper.getWritableDatabase();
    }



    private class CustomSQLiteOpenHelper extends SQLiteOpenHelper {

        public CustomSQLiteOpenHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // This string is used to create the database. It should
            // be changed to suit your needs.

            String newTableQueryString = " create table " + TABLE_NAME
                    + "(" 
                    + ITEM_ID + " integer primary key autoincrement, " 
                    + ITEM_NAME + " text not null, " 
                    + ITEM_PRICE + " integer," 
                    + CURRENT_STOCK + " integer," 
                    + IMAGE + " text "
                    + ");";
            // execute the query string to the database.
            db.execSQL(newTableQueryString);
            addRow();

        }

         @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                db.execSQL("DROP TABLE IF EXISTS "+TABLE_NAME);
                onCreate(db);
            }
    }



    /**********************************************************************
     * ADDING A ROW TO THE DATABASE TABLE
     * 
     * the key is automatically assigned by the database
     * @param name the value for the item name and so on..
     */
    public void addRow()
    {
        try{// this is a key value pair holder used by android's SQLite functions
        ContentValues values = new ContentValues();
        values.put(ITEM_NAME, "Ivory Silk Clutch");
        values.put(ITEM_PRICE, "999");
        values.put(CURRENT_STOCK, "50");
        values.put(IMAGE, R.drawable.ivory_silk);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "Gold Clutch");
        values.put(ITEM_PRICE, "799");
        values.put(CURRENT_STOCK, "10");
        values.put(IMAGE, R.drawable.gold);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "Bridal Clutch");
        values.put(ITEM_PRICE, "899");
        values.put(CURRENT_STOCK, "20");
        values.put(IMAGE, R.drawable.bridal);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "Black Clutch");
        values.put(ITEM_PRICE, "799");
        values.put(CURRENT_STOCK, "20");
        values.put(IMAGE, R.drawable.black);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "evening Clutch");
        values.put(ITEM_PRICE, "999");
        values.put(CURRENT_STOCK, "20");
        values.put(IMAGE, R.drawable.evening_clutch);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "grey Clutch");
        values.put(ITEM_PRICE, "699");
        values.put(CURRENT_STOCK, "20");
        values.put(IMAGE, R.drawable.grey);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "cream Clutch");
        values.put(ITEM_PRICE, "999");
        values.put(CURRENT_STOCK, "15");
        values.put(IMAGE, R.drawable.cream);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "White Tubular Clutch");
        values.put(ITEM_PRICE, "999");
        values.put(CURRENT_STOCK, "25");
        values.put(IMAGE, R.drawable.white_tubular_clutch);
        db.insert(TABLE_NAME, null, values);

        values.put(ITEM_NAME, "Party Clutch");
        values.put(ITEM_PRICE, "999");
        values.put(CURRENT_STOCK, "20");
        values.put(IMAGE, R.drawable.party);
        db.insert(TABLE_NAME, null, values);
        }

        catch(Exception e)
        {
            Log.e("DB ERROR", e.toString());
            e.printStackTrace();
        }
    }


    /**********************************************************************
     * RETRIEVING ALL ROWS FROM THE DATABASE TABLE
     * the key is automatically assigned by the database
     */


    public ArrayList<Item> getAllItemsAsArrays()
    {
        // create an ArrayList that will hold all of the data collected from
        // the database.
        ArrayList<Item> dataArrays = new ArrayList<Item>();
        Item item = new Item();
        // this is a database call that creates a "cursor" object.
        // the cursor object store the information collected from the
        // database and is used to iterate through the data.
        Cursor cursor;

        try
        {
            // ask the database object to create the cursor.
            cursor = db.query(
                    TABLE_NAME,
                    new String[] { ITEM_ID, ITEM_NAME, ITEM_PRICE, CURRENT_STOCK,IMAGE},
                    null, null, null, null, null
            );

            // move the cursor's pointer to position zero.
            cursor.moveToFirst();

            // if there is data after the current cursor position, add it
            // to the ArrayList.
            if (!cursor.isAfterLast())
            {
                do
                {


                    item.setId(cursor.getLong(0));
                    item.setTitle(cursor.getString(1));
                    item.setPrice(cursor.getLong(2));
                    item.setCurrentStock(cursor.getLong(3));
                    item.setProductImage(Integer.parseInt(cursor.getString(4)));

                    dataArrays.add(item);
                }
                // move the cursor's pointer up one position.
                while (cursor.moveToNext());
            }

            cursor.close();
        }
        catch (SQLException e)
        {
            Log.e("DB Error", e.toString());
            e.printStackTrace();
        }

        // return the ArrayList that holds the data collected from
        // the database.
        return dataArrays;
    }
}

ItemScannerActivity.java

package com.demo.itemscanner;

import java.util.ArrayList;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class ItemScannerActivity extends Activity {

    ItemScannerDatabaseManager db;
    TableLayout dataTable;
    //ArrayList<Item> itemList = new ArrayList<Item>();
    private ArrayAdapter<Item> listAdapter ; 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        try {
            // Android specific calls
            super.onCreate(savedInstanceState);
            setContentView(R.layout.dataview);
            ListView list = (ListView)findViewById(R.id.ListViewCatalog);

            // create the database manager object
            db = new ItemScannerDatabaseManager(this);
            for(int i=0; i<db.getAllItemsAsArrays().size();i++){
            listAdapter.add(db.getAllItemsAsArrays().get(i));
            }
            list.setAdapter(listAdapter);
        } catch (Exception e) {
            Log.e("ERROR", e.toString());
            e.printStackTrace();
        }
    }



    @Override
    public void onResume() {
        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

Item.java

package com.demo.itemscanner;

public class Item {
    private long id;
    private String title;
     private int productImage;
     private double price;
     private boolean selected;
     private double currentStock;

     public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getProductImage() {
        return productImage;
    }

    public void setProductImage(int productImage) {
        this.productImage = productImage;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    public double getCurrentStock() {
        return currentStock;
    }

    public void setCurrentStock(double currentStock) {
        this.currentStock = currentStock;
    }


     /*public Item(String title, Drawable productImage, double currentStatus,
       double price) {
      this.title = title;
      this.productImage = productImage;
      this.currentStatus = currentStatus;
      this.price = price;
     }*/
}

xml文件, dataview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="Product Catalog"
        android:textColor="#000000"
        android:textSize="24sp" >
    </TextView>

    <ListView
        android:id="@+id/ListViewCatalog"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:background="#ffffff"
        android:cacheColorHint="#ffffff"
        android:clickable="true" >
    </ListView>

</LinearLayout>

看起来这个表没有在数据库中创建,它在db.insert行中返回空指针异常(TABLE_NAME,null,values);

请告诉我哪里出错,任何帮助将不胜感激。 - 谢谢

1 个答案:

答案 0 :(得分:1)

引发NullPointerException,因为此时db的数据库addRowItemScannerDatabaseManager方法中使用的数据库)为null。如果我是你,我会添加另一个addRow方法,如下所示:

public void addRow(SQLiteDatabase theDb) {
     // Setup the ContentValues object
     ContentValues values = new ContentValues();
     //.. add stuff to values
     // insert in to the database
     theDb.insert(TABLE_NAME, null, values);
}

然后,您可以在onCreate的{​​{1}}方法中使用此方法 ,如下所示:

SQLiteOpenHelper