我一直在研究一种方法,以将“活动”之间的引用传递给我的DataBaseHelper类。我不想在每个新活动中重新创建DataBaseHelper的新实例。
从我所看到的,做到这一点的最好方法是实现android.os.parcelable,这很好。
但是,当我尝试使用以下方法覆盖DataBaseHelper构造函数时:

public DataBaseHelper(Parcel source)


我收到一条错误消息,告诉我该构造函数未定义。
我有点理解这意味着什么,但不确定如何解决此问题并在此类中实现Parcelable。
下面是DatabaseHelper类,可打包代码位于底部。

package com.drager;

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

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

public class DataBaseHelper extends SQLiteOpenHelper implements Parcelable{
    //private static String DB_PATH = "/data/data/com.drager/databases/";
    private static String DB_PATH = Environment.getDataDirectory()+"/data/com.drager/databases/";
    final static String DB_NAME = "myDBName";
    private SQLiteDatabase myDataBase=null;
    private final Context myContext;
    private DataBaseHelper myDbHelper;
    private static String TAG ="MyActivity";

    public DataBaseHelper(Context context){
        super(context, DB_NAME, null, 1);
        this.myContext = context;

    }


    public DataBaseHelper(Parcel source) {
        super(source);
        // TODO Auto-generated constructor stub
    }


    public DataBaseHelper createDataBase() throws IOException{
        boolean dbExist =checkDataBase();
        //SQLiteDatabase db_read =null;
        Log.i(TAG,"############value of dbExist"+dbExist+"##########");
        if (dbExist){
            copyDataBase();
            //db must exist
        }
        else{
        myDbHelper = new DataBaseHelper(myContext);
        myDataBase = myDbHelper.getReadableDatabase();
        myDataBase.close();
        //this.getReadableDatabase();
            //db_read.close();

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

    }

    public Cursor executeStatement(){
        Log.i(TAG,"in execute statement");
        Cursor cursor=null;

        cursor=myDataBase.rawQuery("SELECT _ID, title, value "+
                    "FROM constants ORDER BY title",
                     null);
        return cursor;
    }

    public String[] getTextViewItem(){

        Cursor cursor=null;

        String str="";
        String[] resultsString;
        //store query results in cursor
        cursor=myDataBase.rawQuery("SELECT shrt_description FROM description",
                     null);

        ArrayList strings = new ArrayList();
        for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
            str =cursor.getString(cursor.getColumnIndex("shrt_description"));
            strings.add(str);
        }
         resultsString =(String[])strings.toArray(new String[strings.size()]);

         close();//close database after use
        return resultsString;
    }

public String[] getDetailedDescription(){

        Cursor cursor=null;

        String str="";
        String[] resultsString;
        //store query results in cursor
        cursor=myDataBase.rawQuery("SELECT detailed_description FROM description",
                     null);

        ArrayList strings = new ArrayList();
        for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
            str =cursor.getString(cursor.getColumnIndex("detailed_description"));
            strings.add(str);
        }
         resultsString =(String[])strings.toArray(new String[strings.size()]);

         close();//close database after use
        return resultsString;
    }

    public void copyDataBase() throws IOException{
        // open db as input stream
        InputStream myInput;
        //open empty db as output stream
        OutputStream myOutPut;
        try {
            myInput = myContext.getAssets().open(DB_NAME);

            //path to newly created db
            String outFileName =DB_PATH + DB_NAME;

            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);
            }
            myOutPut.flush();
            myOutPut.close();
            myInput.close();
            }
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }




    }

    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;

        String myPath = DB_PATH + DB_NAME;

        try {
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
        } catch (SQLException e) {

            e.printStackTrace();
            return false;
        }

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

    public void openDataBase()throws SQLException{
        //open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }

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

    @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

    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // TODO Auto-generated method stub
        dest.writeParcelable((Parcelable) myDataBase, 0);
        dest.writeString(DB_PATH);
        dest.writeString(DB_NAME);
        dest.writeString(TAG);
        dest.writeParcelable((Parcelable) myContext, 0);
        dest.writeParcelable(myDbHelper, 0);

    }

    public static final Parcelable.Creator<DataBaseHelper> CREATOR = new Parcelable.Creator<DataBaseHelper>() {

        @Override
        public DataBaseHelper createFromParcel(Parcel source) {
            // TODO Auto-generated method stub

            return new DataBaseHelper(source);
        }

        @Override
        public DataBaseHelper[] newArray(int size) {
            // TODO Auto-generated method stub
            return null;
        }

    };

}


任何帮助,不胜感激。
提前致谢。

最佳答案

您似乎不必要地使事情复杂化。你说:


  我不想重新创建新实例
  每个新数据库中的DataBaseHelper
  活动。从我所看到的
  最好的方法是实施
  android.os.parcelable,这很好。


但是,从宗地还原DataBaseHelper对象确实会创建DataBaseHelper类的新实例。这是比创建新的DataBaseHelper困难的方法。

无论如何,尽管您没有在此处复制和粘贴错误消息,但我想我知道您收到了什么错误:不是您的DataBaseHelper类没有包含正确的构造函数;而是是的。这是超类SQLiteOpenHelper没有实现Parcelable。解决此问题的唯一方法是自己管理所有SQLiteOpenHelper状态。也就是说,将SQLiteOpenHelper的状态包含在writeToParcel的实现中,并将该状态恢复为DatabaseHelper(Parcel)的一部分。然后,构造函数将调用SQLiteOpenHelper的默认构造函数。生成的构造函数如下所示:

public DataBaseHelper(Parcel source, Context context, String name,
                      SQLiteDatabase.CursorFactory factory, int version) {
    // NOTE: You've got to pass in an appropriate Context; I'm sure it would not work
    // to try to include the original Activity in the Parcel! That means that your
    // constructor **must** include the Context as one of its arguments. Conceivably,
    // the name, factory, and version could be taken from the Parcel rather than being
    // passed in the constructor arguments. Again, I ask: Is it worth the hassle?
    super(context, name, factory, version);

    // First, restore any relevant `SQLiteOpenHelper` state...
           //...
    // Now restore any relevant DataBaseHelper state...
           //...
}


我认为这不值得付出努力,但这取决于您自己决定。

关于java - 在DataBaseHelper类中实现Parcelable,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4993667/

10-10 20:11