如何在android中使用外部数据库

时间:2016-03-06 13:44:39

标签: android android-fragments android-database

我想在我的应用中使用 External database 。在我的应用程序中有4 fragment,并在数据库中显示任何一个表的数据库(数据库有4个表)。但是当开始运行应用程序时,请显示以下错误:

03-06 16:59:46.350 9654-9654/com.tellfa.dastanak E/AndroidRuntime: FATAL EXCEPTION: main
                                                               Process: com.tellfa.dastanak, PID: 9654
                                                               java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.Cursor android.database.sqlite.SQLiteDatabase.rawQuery(java.lang.String, java.lang.String[])' on a null object reference
                                                                   at com.tellfa.dastanak.Database.DataBase.getCat1_Datas2(DataBase.java:156)
                                                                   at com.tellfa.dastanak.Fragments.Home_Frag.refreshData(Home_Frag.java:58)
                                                                   at com.tellfa.dastanak.Fragments.Home_Frag.onCreateView(Home_Frag.java:49)
                                                                   at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
                                                                   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
                                                                   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
                                                                   at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
                                                                   at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
                                                                   at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
                                                                   at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
                                                                   at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
                                                                   at android.support.v4.view.ViewPager.populate(ViewPager.java:952)
                                                                   at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1474)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
                                                                   at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:610)
                                                                   at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:677)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:940)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
                                                                   at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
                                                                   at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
                                                                   at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
                                                                   at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
                                                                   at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
                                                                   at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
                                                                   at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
                                                                   at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
                                                                   at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
                                                                   at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
                                                                   at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2636)
                                                                   at android.view.View.measure(View.java:17496)
                                                                   at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2031)
                                                                   at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1193)
                                                                   at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1400)
                                                                   at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1078)
                                                                   at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5875)
                                                                   at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
                                                                   at android.view.Choreographer.doCallbacks(Choreographer.java:580)
                                                                   at android.view.Choreographer.doFrame(Choreographer.java:550)
                                                                   at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
                                                                   at android.os.Handler.handleCallback(Handler.java:739)
                                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                   at android.os.Looper.loop(Looper.java:135)
                                                                   at android.app.ActivityThread.main(ActivityThread.java:5349)
                                                                at java.lang.reflect.Met

数据库代码:

public class DataBase extends SQLiteOpenHelper {

    private static String DB_PATH = "";
    private static String DB_NAME = "Dastansara";
    private static int DB_VERSION = 1;
    private SQLiteDatabase sqLiteDatabase;
    private final Context myContext;

    /**
     * Constructor
     * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
     *
     * @param context
     */
    public DataBase(Context context) {
        super(context, DB_NAME, null, DB_VERSION);

        if (android.os.Build.VERSION.SDK_INT >= 17) {
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        } else {
            DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        }

        this.myContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

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

    /**
     * Creates a empty database on the system and rewrites it with your own database.
     */
    public void createDataBase() throws IOException {

        boolean dbExist = checkDataBase();
        if (dbExist) {
            // do nothing - database alerdy exist
        } else {

            this.getReadableDatabase();

            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    /**
     * Check if the database already exist to avoid re-copying the file each time you open the application.
     *
     * @return true if it exists, false if it doesn't
     */
    public boolean checkDataBase() {

        SQLiteDatabase checkDB = null;
        try {
            String myPATH = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPATH, null, SQLiteDatabase.OPEN_READONLY);

        } catch (SQLiteException e) {
            /// database does't exist yet
        }

        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    /**
     * Open DataBase
     *
     * @throws SQLException
     */
    public void openDataBase() throws SQLException {

        String myPATH = DB_PATH + DB_NAME;
        sqLiteDatabase = SQLiteDatabase.openDatabase(myPATH, null, SQLiteDatabase.OPEN_READONLY);
    }

    /**
     * Close DataBase
     */
    public void closeDataBase() {

        sqLiteDatabase.close();
    }

    /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     */
    public void copyDataBase() throws IOException {

        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        // Path to the just created empty db
        String myPath = DB_PATH + DB_NAME;
        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(myPath);

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

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

    public Cursor getCat1_Datas2() {

        try {
            String query = "SELECT * FROM tbl_Book WHERE Cat_ID = 1";
            Cursor cursor = sqLiteDatabase.rawQuery(query, null);

            if (cursor != null) {
                cursor.moveToNext();
            }
            return cursor;
        } catch (SQLException e) {
            Log.e("Data Adapter", "getTestData >>" + e.toString());
            throw e;
        }
    }

DataProvider代码:

public class DataProvider {

    int _id, _catID, _fav;
    String _title, _description;
    byte[] _image;

    public DataProvider(int key_id, int key_catID, int key_fav, String key_title, String key_description, byte[] key_image) {
        this._id = key_id;
        this._catID = key_catID;
        this._fav = key_fav;
        this._title = key_title;
        this._description = key_description;
        this._image = key_image;
    }

    /// Empty Constructor
    public DataProvider(){

    }

    public DataProvider(int key_id, String key_title){
        this._id = key_id;
        this._title = key_title;
    }

    public byte[] getKey_image() {
        return _image;
    }

    public void setKey_image(byte[] key_image) {
        _image = key_image;
    }

    public String getKey_description() {
        return _description;
    }

    public void setKey_description(String key_description) {
        _description = key_description;
    }

    public String getKey_title() {
        return _title;
    }

    public void setKey_title(String key_title) {
        _title = key_title;
    }

    public int getKey_fav() {
        return _fav;
    }

    public void setKey_fav(int key_fav) {
        _fav = key_fav;
    }

    public int getKey_catID() {
        return _catID;
    }

    public void setKey_catID(int key_catID) {
        _catID = key_catID;
    }

    public int getKey_id() {
        return _id;
    }

    public void setKey_id(int key_id) {
        _id = key_id;
    }

}

片段代码:

public class Home_Frag  extends Fragment {

    DataProvider dataProvider;
    DataBase dataBase;
    SQLiteDatabase sqLiteDatabase;
    Cursor cursor;
    ListView listView;
    Cat1_frag_adapter cat1FragAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.frag_home,
                container, false);

        refreshData();

        return rootView;
    }

    public void refreshData(){

        dataBase = new DataBase(getActivity());
        sqLiteDatabase = dataBase.getReadableDatabase();
        cursor = dataBase.getCat1_Datas2();

        listView = (ListView) getActivity().findViewById(R.id.list);
        cat1FragAdapter = new Cat1_frag_adapter(getActivity(), R.layout.list_card_layout);
        listView.setAdapter(cat1FragAdapter);

        if (cursor.moveToFirst()){
            do {
                int id, catID, fav;
                String title, desvription;
                byte[] image;
                id = cursor.getInt(0);
                title = cursor.getString(2);

                dataProvider = new DataProvider(id, title);
                cat1FragAdapter.add(dataProvider);

            } while (cursor.moveToNext());
        }
    }
}

如何解决这个问题? tnx all< 3

1 个答案:

答案 0 :(得分:1)

你的问题在这里:

public Cursor getCat1_Datas2() {

        try {
            String query = "SELECT * FROM tbl_Book WHERE Cat_ID = 1";
            Cursor cursor = sqLiteDatabase.rawQuery(query, null);

            if (cursor != null) {
                cursor.moveToNext();
            }
            return cursor;
        } catch (SQLException e) {
            Log.e("Data Adapter", "getTestData >>" + e.toString());
            throw e;
        }
    }

正在提供NullPointerException,因为如http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html

所述
  

sql String:SQL查询。不得终止SQL字符串

     

selectionArgs字符串:您可以包括?在查询中的where子句中,它将被selectionArgs中的值替换。这些值将绑定为字符串。

所以你需要做的就是将你的代码更改为:

public Cursor getCat1_Datas2() {

        try {
            String query = "SELECT * FROM tbl_Book WHERE Cat_ID = ?";

            Cursor cursor = sqLiteDatabase.rawQuery(query, new String[] {"1"});

            if (cursor != null) {
                cursor.moveToNext();
            }
            return cursor;
        } catch (SQLException e) {
            Log.e("Data Adapter", "getTestData >>" + e.toString());
            throw e;
        }
    }

在您onCreateView的{​​{1}}方法中,您有这个:

Fragment

像这样修改你的方法:

dataBase = new DataBase(getActivity());
sqLiteDatabase = dataBase.getReadableDatabase();
cursor = dataBase.getCat1_Datas2();

然后在public Cursor getCat1_Datas2(SQLiteDatabase sqLiteDatabase) { try { String query = "SELECT * FROM tbl_Book WHERE Cat_ID = ?"; Cursor cursor = sqLiteDatabase.rawQuery(query, new String[] {"1"}); if (cursor != null) { cursor.moveToNext(); } return cursor; } catch (SQLException e) { Log.e("Data Adapter", "getTestData >>" + e.toString()); throw e; } } 试试这个:

OnCreateView()

dataBase = new DataBase(getActivity()); sqLiteDatabase = dataBase.getReadableDatabase(); cursor = sqLiteDatabase.getCat1_Datas2(sqLiteDatabase); 方法修改为:

refreshData()

然后像这样调用它:

public void refreshData(View view){

        dataBase = new DataBase(getActivity());
        sqLiteDatabase = dataBase.getReadableDatabase();
        cursor = dataBase.getCat1_Datas2();

        listView = (ListView) view.findViewById(R.id.list);
        cat1FragAdapter = new Cat1_frag_adapter(getActivity(), R.layout.list_card_layout);
        listView.setAdapter(cat1FragAdapter);

        if (cursor.moveToFirst()){
            do {
                int id, catID, fav;
                String title, desvription;
                byte[] image;
                id = cursor.getInt(0);
                title = cursor.getString(2);

                dataProvider = new DataProvider(id, title);
                cat1FragAdapter.add(dataProvider);

            } while (cursor.moveToNext());
        }
    }

希望它有所帮助!!!