获取java.lang.nullPointerException以从现有数据库填充

时间:2015-04-11 23:15:03

标签: java android sqlite

我有一个我创建的现有数据库,我希望从中获取数据以填充android中的listview。现在我首先想让我的数据库连接并正常工作,看看我是否可以从中获取数据。我的数据库名为HealthySizing,其中有一个有6列的衬衫表。所以我有一个DBHelper类,一个MainActivity.java和一个activity_main.xml,我已经发布了这三个文件以及我得到的错误,所以有人可以帮我解决这个问题吗?有谁知道我为什么会收到此错误以及如何修复它以从我的数据库中获取一些数据?

package com.example.ListViewFromSQLiteDB;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;

public class DBHelper extends SQLiteOpenHelper {

    private static final String DATABASE_PATH = "/data/data/com.example.ListViewFromSQLiteDB/databases";
    private static final String DATABASE_NAME = "HealthySizing.db";
    private static final int SCHEMA_VERSION = 1;
    public SQLiteDatabase dbSqlite;
    private final Context myContext;
    public static String tableName = "Shirts";

    public DBHelper(Context context) {
        super(context, DATABASE_NAME, null, SCHEMA_VERSION);
        this.myContext = context;
    }

    public void onCreate(SQLiteDatabase db) {

    }

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

    }

    public void createDatabase() {
        createDB();
    }

    private void createDB() {

        boolean dbExist = DBExists();

        if (!dbExist) {

            this.getReadableDatabase();
            copyDBFromResource();

        }

    }

    private boolean DBExists() {

        SQLiteDatabase db = null;

        try {

            String databasePath = DATABASE_PATH + DATABASE_NAME;
            db = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.OPEN_READWRITE);
            db.setLocale(Locale.getDefault());
            db.setLockingEnabled(true);
            db.setVersion(1);

        } catch (SQLiteException e) {
            Log.e("SqlHelper", "database not found");
        }

        if (db != null) {
            db.close();
        }

        return db != null ? true : false;

    }

    private void copyDBFromResource() {

        InputStream inputStream = null;
        OutputStream outStream = null;
        String dbFilePath = DATABASE_PATH + DATABASE_NAME;

        try {

            inputStream = myContext.getAssets().open(DATABASE_NAME);
            outStream = new FileOutputStream(dbFilePath);

            byte[] buffer = new byte[1024];
            int length;

            while((length = inputStream.read(buffer)) > 0) {
                outStream.write(buffer, 0, length);
            }

            outStream.flush();
            outStream.close();
            inputStream.close();

        } catch (IOException e) {
            throw new Error("Problem copying database from resource file");
        }

    }

    @Override
    public synchronized void close() {
        if (dbSqlite != null) {
            dbSqlite.close();
        }
        super.close();
    }

}

/*public class DBHelper extends SQLiteOpenHelper{

    public SQLiteDatabase DB;
    public String DBPath;
    public static String DBName = "HealthySizing";
    public static final int version = '3';
    public static Context currentContext;
    public static String tableName = "Shirts";

    public DBHelper(Context context) {
        super(context, DBName, null, version);
        currentContext = context;
        DBPath = "/data/data/" + context.getPackageName() + "/databases";
        createDatabase();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

    private void createDatabase() {

        boolean dbExists = checkDbExists();

        if (dbExists) {
            // do nothing
        }




    }

    private boolean checkDbExists() {
        SQLiteDatabase checkDB = null;

        try {
            String myPath = DBPath + DBName;
            checkDB = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);

        } catch (SQLiteException e) {

            // database doesn't exist yet.

        }

        if (checkDB != null) {

            checkDB.close();

        }

        return checkDB != null ? true : false;
    }

}
    */
package com.example.ListViewFromSQLiteDB;

import java.util.ArrayList;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class MainActivity extends ListActivity {

    private ArrayList<String> results = new ArrayList<String>();
    private String tableName = DBHelper.tableName;
    private SQLiteDatabase newDB;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        openAndQueryDatabase();
        displayResultList();

    }
    private void displayResultList() {
        TextView tView = new TextView(this);
        //tView.setText("This data is retrieved from the database and only 4 " +
        //        "of the results are displayed");
        getListView().addHeaderView(tView);

        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, results));
        getListView().setTextFilterEnabled(true);

    }
    private void openAndQueryDatabase() {
        try {
            DBHelper dbHelper = new DBHelper(this.getApplicationContext());
            newDB = dbHelper.getWritableDatabase();

            Cursor c = newDB.rawQuery("SELECT Brand  FROM " +
                    tableName, null);

            if (c != null ) {
                if  (c.moveToFirst()) {
                    do {
                        String brand = c.getString(c.getColumnIndex("Brand"));
                        results.add(brand);

                    }while (c.moveToNext());
                }
            }
        } catch (SQLiteException se ) {
            Log.e(getClass().getSimpleName(), "Could not create or Open the database");
        } finally {
            if (newDB != null)
                newDB.execSQL("DELETE FROM " + tableName);
            newDB.close();
        }

    }

}
04-11 15:41:48.558    1923-1923/com.example.ListViewFromSQLiteDB I/art﹕ Not late-enabling -Xcheck:jni (already on)
04-11 15:41:51.974    1923-1923/com.example.ListViewFromSQLiteDB E/MainActivity﹕ Could not create or Open the database
04-11 15:41:51.975    1923-1923/com.example.ListViewFromSQLiteDB D/AndroidRuntime﹕ Shutting down VM
    --------- beginning of crash
04-11 15:41:51.975    1923-1923/com.example.ListViewFromSQLiteDB E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.ListViewFromSQLiteDB, PID: 1923
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ListViewFromSQLiteDB/com.example.ListViewFromSQLiteDB.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.database.sqlite.SQLiteDatabase.close()' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
            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)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.database.sqlite.SQLiteDatabase.close()' on a null object reference
            at com.example.ListViewFromSQLiteDB.MainActivity.openAndQueryDatabase(MainActivity.java:59)
            at com.example.ListViewFromSQLiteDB.MainActivity.onCreate(MainActivity.java:22)
            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)
device not found

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ListViewFromSQLiteDB"
    android:versionCode="1"
    android:versionName="1.0">
    <application android:icon="@drawable/ic_launcher" android:label="@string/app_name">
        <activity android:name="com.example.ListViewFromSQLiteDB.MainActivity"
            android:label="@string/app_name">
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1">
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello"
        android:layout_weight="0.12" />
</LinearLayout>

2 个答案:

答案 0 :(得分:0)

在openAndQueryDatabase的finally块中,调用newDB.close()而不检查它是否为null。试试这个:

} finally { 
    if (newDB != null){
        newDB.execSQL("DELETE FROM " + tableName); 
        newDB.close();
    }
}

答案 1 :(得分:0)

试试这个

finally {
        try {
            if (newDB != null){
                newDB.execSQL("DELETE FROM " + tableName );
            newDB.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }