尝试打印数据库行时出现NullPointErexception

时间:2014-01-21 19:59:51

标签: java android database sqlite nullpointerexception

访问应用页面'CurrentItems'时,请关闭并显示以下错误:

01-21 19:51:54.474: E/AndroidRuntime(10418): FATAL EXCEPTION: main
01-21 19:51:54.474: E/AndroidRuntime(10418): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fooditemmonitor/com.example.fooditemmonitor.CurrentItems}: java.lang.NullPointerException
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.ActivityThread.access$700(ActivityThread.java:159)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.os.Looper.loop(Looper.java:176)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.ActivityThread.main(ActivityThread.java:5419)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at java.lang.reflect.Method.invokeNative(Native Method)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at java.lang.reflect.Method.invoke(Method.java:525)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at dalvik.system.NativeStart.main(Native Method)
01-21 19:51:54.474: E/AndroidRuntime(10418): Caused by: java.lang.NullPointerException
01-21 19:51:54.474: E/AndroidRuntime(10418):    at com.example.fooditemmonitor.CurrentItems.updateTable(CurrentItems.java:65)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at com.example.fooditemmonitor.CurrentItems.onCreate(CurrentItems.java:34)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.Activity.performCreate(Activity.java:5372)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
01-21 19:51:54.474: E/AndroidRuntime(10418):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
01-21 19:51:54.474: E/AndroidRuntime(10418):    ... 11 more

CurrentItems

package com.example.fooditemmonitor;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class CurrentItems extends Activity {

    ItemDatabase db;
    Context context;
    Button addButton;

    // the table that displays the data
    TableLayout dataTable;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.current_inventory);

        db = new ItemDatabase(this);

        // bring up current database items
        updateTable();

        // create references and listeners for the GUI interface
        setupViews();

        // make the buttons clicks perform actions
        addButtonListeners();
    }

    private void setupViews() {
        // THE DATA TABLE
        dataTable = (TableLayout) findViewById(R.id.currentTable);

        // THE BUTTONS
        addButton = (Button) findViewById(R.id.scanCurrent);
    }

    private void addButtonListeners() {

        addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(CurrentItems.this, AddItem.class));
                ;
            }
        });
    }

    private void updateTable() {
        // delete all but the first row. remember that the count starts at one
        // and the index starts at zero
        while (dataTable.getChildCount() > 1) {
            // while there are at least two rows in the table widget, delete
            // the second row.
            dataTable.removeViewAt(1);
        }

        // collect the current row information from the database and
        // store it in a two dimensional ArrayList
        ArrayList<ArrayList<Object>> data = db.getAllRowsAsArrays();

        // iterate the ArrayList, create new rows each time and add them
        // to the table widget.
        for (int position = 0; position < data.size(); position++) {
            TableRow tableRow = new TableRow(this);

            ArrayList<Object> row = data.get(position);

            TextView dateData = new TextView(this);
            dateData.setText(row.get(1).toString());
            tableRow.addView(dateData);

            TextView quantityData = new TextView(this);
            quantityData.setText(row.get(4).toString());
            tableRow.addView(quantityData);

            TextView titleData = new TextView(this);
            titleData.setText(row.get(3).toString());
            tableRow.addView(titleData);

            dataTable.addView(tableRow);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }
}

ItemDatabase

package com.example.fooditemmonitor;

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 final class ItemDatabase {

    // 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.
    private final String DATABASE_NAME = "ItemDatabase.sqlite";
    private final int DATABASE_VERSION = 1;

    // These constants are specific to the database table.
    private final String TABLE_NAME = "foodItems";
    private final String COLUMN_NAME_ENTRY_ID = "entryid";
    private final String COLUMN_NAME_BARCODE = "barcode";
    private final String COLUMN_NAME_TITLE = "title";
    private final String COLUMN_NAME_QUANTITY = "quantity";
    private final String COLUMN_NAME_DATE = "date";

    public ItemDatabase(Context context) {
        this.context = context;

        // create or open the database
        ItemDatabaseHelper helper = new ItemDatabaseHelper(context);
        this.db = helper.getWritableDatabase();
    }

    public void addRow(String rowStringOne, String rowStringTwo,
            String rowStringThree, int rowIntFour) {
        // this is a key value pair holder used by android's SQLite functions
        ContentValues values = new ContentValues();
        values.put(COLUMN_NAME_DATE, rowStringOne);
        values.put(COLUMN_NAME_BARCODE, rowStringTwo);
        values.put(COLUMN_NAME_TITLE, rowStringThree);
        values.put(COLUMN_NAME_QUANTITY, rowIntFour);

        // ask the database object to insert the new data
        try {
            db.insert(TABLE_NAME, null, values);
        } catch (Exception e) {
            Log.e("DB ERROR", e.toString());
            e.printStackTrace();
        }
    }

    public void updateRow(long rowID, String rowStringOne, String rowStringTwo,
            String rowStringThree, int rowIntFour) {
        // this is a key value pair holder used by android's SQLite functions
        ContentValues values = new ContentValues();
        values.put(COLUMN_NAME_DATE, rowStringOne);
        values.put(COLUMN_NAME_BARCODE, rowStringTwo);
        values.put(COLUMN_NAME_TITLE, rowStringThree);
        values.put(COLUMN_NAME_QUANTITY, rowIntFour);

        // ask the database object to update the database row of given rowID
        try {
            db.update(TABLE_NAME, values, COLUMN_NAME_ENTRY_ID + "=" + rowID,
                    null);
        } catch (Exception e) {
            Log.e("DB Error", e.toString());
            e.printStackTrace();
        }
    }

    public void deleteRow(long rowID) {
        // ask the database manager to delete the row of given id
        try {
            db.delete(TABLE_NAME, COLUMN_NAME_ENTRY_ID + "=" + rowID, null);
        } catch (Exception e) {
            Log.e("DB ERROR", e.toString());
            e.printStackTrace();
        }
    }

    public ArrayList<ArrayList<Object>> getAllRowsAsArrays() {
        // create an ArrayList that will hold all of the data collected from
        // the database.
        ArrayList<ArrayList<Object>> dataArrays = new ArrayList<ArrayList<Object>>();

        // 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[] { COLUMN_NAME_DATE,
                    COLUMN_NAME_QUANTITY, COLUMN_NAME_TITLE }, null, null,
                    null, null, COLUMN_NAME_TITLE + " DESC");

            // 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 {
                    ArrayList<Object> dataList = new ArrayList<Object>();

                    dataList.add(cursor.getString(1));
                    dataList.add(cursor.getInt(4));
                    dataList.add(cursor.getString(3));

                    dataArrays.add(dataList);
                }
                // move the cursor's pointer up one position.
                while (cursor.moveToNext());
            }
        } catch (SQLException e) {
            Log.e("DB Error", e.toString());
            e.printStackTrace();
        }

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

    public class ItemDatabaseHelper extends SQLiteOpenHelper {
        public ItemDatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        public void onCreate(SQLiteDatabase db) {
            String newTableQueryString = "create table " + TABLE_NAME + " ("
                    + COLUMN_NAME_ENTRY_ID
                    + " integer primary key autoincrement not null,"
                    + COLUMN_NAME_DATE + " date," + COLUMN_NAME_BARCODE
                    + " text," + COLUMN_NAME_TITLE + " text"
                    + COLUMN_NAME_QUANTITY + " int" + ");";
            // execute the query string to the database.
            db.execSQL(newTableQueryString);
        }

        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        }
    }
}

第65行:

while (dataTable.getChildCount() > 1) {

从显示的消息中,数据似乎正在进入数据库,但尝试访问它会导致错误。我没看到语法错误或拼写错误。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

dataTable仅在您的应用中稍后初始化(setupViews())。当你致电updateTable()时,它尚未初始化。

通常这些问题很容易自行调试。正如您已经找到导致NPE的代码行。在这种情况下,NPE代码行的唯一方法是dataTablenull时。然后回读代码以检查变量初始化的位置(如果有的话)以及何时发生,与NPE行相关。

此特定问题的修复很简单:只需在setupViews()中切换订单或updateTable()onCreate()

答案 1 :(得分:1)

dataTable = (TableLayout) findViewById(R.id.currentTable);

之前放置updateTable()