Ошибка с программой базы данных Android - PullRequest
0 голосов
/ 29 июня 2010
06-29 01:24:15.882: ERROR/AndroidRuntime(747): Uncaught handler: thread main exiting due to uncaught exception
06-29 01:24:15.922: ERROR/AndroidRuntime(747): java.lang.RuntimeException: Unable to start activity ComponentInfo{one.two/one.two.Arrival}: java.lang.NullPointerException
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2268)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.app.ActivityThread.access$1800(ActivityThread.java:112)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1692)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.os.Looper.loop(Looper.java:123)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.app.ActivityThread.main(ActivityThread.java:3948)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at java.lang.reflect.Method.invokeNative(Native Method)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at java.lang.reflect.Method.invoke(Method.java:521)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at dalvik.system.NativeStart.main(Native Method)
06-29 01:24:15.922: ERROR/AndroidRuntime(747): Caused by: java.lang.NullPointerException
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at one.two.DBAdapter.getAllTitles(DBAdapter.java:167)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at one.two.Arrival.getData(Arrival.java:35)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at one.two.Arrival.onCreate(Arrival.java:21)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)
06-29 01:24:15.922: ERROR/AndroidRuntime(747):     ... 11 more

Мой класс для вызова базы данных

package one.two;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class Arrival extends ListActivity
{
    private ListView listView;
    DBAdapter db = new DBAdapter(this);

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        getData();
        // db.open();
        listView = (ListView) findViewById(android.R.id.list);
        // db.close();
    }

    private void getData()
    {
        // show some display that you are going to open db
        db.open();
        // show some display that you have opened

        // redundant see below statement ---- List<String> items = new ArrayList<String>();
        // call the DBAdapter method to getAllTitles()
        List<String> items = DBAdapter.getAllTitles();
        // iterate through the items one by one thru display statement or show
        // on layout
        // check how to do that

        ArrayAdapter<String> titles = new ArrayAdapter<String>(this,
                R.layout.main, items);

        db.close();
    }

}

Мой DBAdapter.java

package one.two;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.ArrayList;

public class DBAdapter extends ListActivity
{
    private static String DB_PATH = "/data/data/one.two/databases/";
    private static final String DATABASE_NAME = "ferry.db";
    private static final String DATABASE_TABLE = "port";
    public static Context context;

    public String status = "status";
    public String id = "id";
    public String arrival = "arrival";
    public String destination = "destination";
    public String ferry = "ferry";

    //null constructor
    public DBAdapter()
    {

    }

    //overloaded non-null constructor
    public DBAdapter(Context context)
    {

    }

    public class DatabaseHelper extends SQLiteOpenHelper
    {
        Context context;
        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.context = context;

        }//end constructor DatabaseHelper

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion,
                int newVersion)
        {
        }//end onUpgrade()

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            boolean dbExist = checkDatabase();

            if (dbExist)
            {
            }
            else
            {
                this.getReadableDatabase();
                try
                {
                    copyDataBase();
                }
                catch (IOException e)
                {
                    throw new Error("Error copying database");
                }
            }
        }//end onCreate()
    }// end class DatabaseHelper

    private static DatabaseHelper DBHelper;
    private static SQLiteDatabase db;

    private static final int DATABASE_VERSION = 1;

    //// context brought up /////////////
    //private final Context context;


        private boolean checkDatabase()
        {
            SQLiteDatabase checkDB = null;
            try
            {
                String myPath = DB_PATH + DATABASE_NAME;
                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;
        }//end checkDatabase()

        private void copyDataBase() throws IOException
        {

            // Open your local db as the input stream
            InputStream myInput = context.getAssets().open(DATABASE_NAME);

            // Path to the just created empty db
            String outFileName = DB_PATH + DATABASE_NAME;

            // Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(outFileName);

            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0)
            {
                myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();

        }//end copyDataBase()

        public void DBAdapter() throws SQLException
        {
            String myPath = DB_PATH + DATABASE_NAME;
            db = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        }//end DBAdapter()
        public void open()
        {
            //Open the database
            String myPath = DB_PATH + DATABASE_NAME;
            db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

        }
        // ---closes the database---
        public void close()
        {
            DBHelper.close();
        }//end close()

        public static List<String> getAllTitles()
        {

            List<String> titles = new ArrayList<String>();

                Cursor c=null;
                c = db.query("port",
                        new String[] { "status", "id", "arrival",
                                "destination", "ferry" }, null, null,
                        null, null, null);
                try {
                    if (c!=null) {
                        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) 
                        {
                            DBAdapter title = new DBAdapter(context);
                            title.status = c.getString(0);
                            title.id = c.getString(1);
                            title.arrival = c.getString(2);
                            title.destination = c.getString(3);
                            title.ferry = c.getString(4);
                        }
                    }
                } finally {
                    if (c!=null) {
                    c.close();
                }

        }
            return titles;
        }//end getAllTitles()
    }//end class DBAdapter

1 Ответ

2 голосов
/ 29 июня 2010

Вы никогда не звоните open() на вашем объекте. Вы используете статический вызов в своем коде, но этот статический вызов зависит от нестатических методов, вызываемых для установки членов статических данных. Поэтому, когда вы вызываете db.query() db, значение равно нулю, следовательно, исключение нулевого указателя. Ваша общая архитектура в корне ошибочна. Вам нужно создать экземпляр вашего объекта DBAdapter и вызвать несколько методов, таких как open, из вашего статического метода. Однако внутри статического метода вы полагаетесь на устанавливаемый объект context. Однако вы не установите это, пока не вызовете конструктор. Вы должны убедиться, что ваши ссылки установлены, прежде чем пытаться работать с ними. Я бы посоветовал не пытаться делать статический вызов, подобный этому, если вы не хотите передать ему объект Context. Оттуда вам потребуется создать экземпляр объекта DBAdapter и вызвать соответствующие методы настройки (например, open), прежде чем вы сможете взаимодействовать с базой данных.

Редактировать

На основе перечитывания кода измените класс адаптера базы данных, чтобы удалить статический метод:

package one.two;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import android.app.ListActivity;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.ArrayList;

public class DBAdapter extends ListActivity
{
    private static String DB_PATH = "/data/data/one.two/databases/";
    private static final String DATABASE_NAME = "ferry.db";
    private static final String DATABASE_TABLE = "port";
    public static Context context;

    public String status = "status";
    public String id = "id";
    public String arrival = "arrival";
    public String destination = "destination";
    public String ferry = "ferry";

    //null constructor
    public DBAdapter()
    {

    }

    //overloaded non-null constructor
    public DBAdapter(Context context)
    {

    }

    public class DatabaseHelper extends SQLiteOpenHelper
    {
        Context context;
        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            this.context = context;

        }//end constructor DatabaseHelper

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion,
                int newVersion)
        {
        }//end onUpgrade()

        @Override
        public void onCreate(SQLiteDatabase db)
        {
            boolean dbExist = checkDatabase();

            if (dbExist)
            {
            }
            else
            {
                this.getReadableDatabase();
                try
                {
                    copyDataBase();
                }
                catch (IOException e)
                {
                    throw new Error("Error copying database");
                }
            }
        }//end onCreate()
    }// end class DatabaseHelper

    private static DatabaseHelper DBHelper;
    private static SQLiteDatabase db;

    private static final int DATABASE_VERSION = 1;

    //// context brought up /////////////
    //private final Context context;


        private boolean checkDatabase()
        {
            SQLiteDatabase checkDB = null;
            try
            {
                String myPath = DB_PATH + DATABASE_NAME;
                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;
        }//end checkDatabase()

        private void copyDataBase() throws IOException
        {

            // Open your local db as the input stream
            InputStream myInput = context.getAssets().open(DATABASE_NAME);

            // Path to the just created empty db
            String outFileName = DB_PATH + DATABASE_NAME;

            // Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(outFileName);

            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0)
            {
                myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();

        }//end copyDataBase()

        public void DBAdapter() throws SQLException
        {
            String myPath = DB_PATH + DATABASE_NAME;
            db = SQLiteDatabase.openDatabase(myPath, null,
                    SQLiteDatabase.OPEN_READONLY);
        }//end DBAdapter()
        public void open()
        {
            //Open the database
            String myPath = DB_PATH + DATABASE_NAME;
            db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

        }
        // ---closes the database---
        public void close()
        {
            DBHelper.close();
        }//end close()

        public List<String> getAllTitles()
        {

            List<String> titles = new ArrayList<String>();

                Cursor c=null;
                c = db.query("port",
                        new String[] { "status", "id", "arrival",
                                "destination", "ferry" }, null, null,
                        null, null, null);
                try {
                    if (c!=null) {
                        for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) 
                        {
                            DBAdapter title = new DBAdapter(context);
                            title.status = c.getString(0);
                            title.id = c.getString(1);
                            title.arrival = c.getString(2);
                            title.destination = c.getString(3);
                            title.ferry = c.getString(4);
                        }
                    }
                } finally {
                    if (c!=null) {
                    c.close();
                }

        }
            return titles;
        }//end getAllTitles()
    }//end class DBAdapter

И измените класс прибытия на нестатический метод:

package one.two;

import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class Arrival extends ListActivity
{
    private ListView listView;
    DBAdapter db = new DBAdapter(this);

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        getData();
        // db.open();
        listView = (ListView) findViewById(android.R.id.list);
        // db.close();
    }

    private void getData()
    {
        // show some display that you are going to open db
        db.open();
        // show some display that you have opened

        // redundant see below statement ---- List<String> items = new ArrayList<String>();
        // call the DBAdapter method to getAllTitles()
        List<String> items = db.getAllTitles();
        // iterate through the items one by one thru display statement or show
        // on layout
        // check how to do that

        ArrayAdapter<String> titles = new ArrayAdapter<String>(this,
                R.layout.main, items);

        db.close();
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...