gpt4 book ai didi

java - 在 DataBaseHelper 类中实现 Parcelable

转载 作者:行者123 更新时间:2023-12-02 08:23:38 25 4
gpt4 key购买 nike

我一直在研究一种在 Activity 之间传递引用到我的 DataBaseHelper 类的方法。我不想在每个新 Activity 中重新创建 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;
}

};

}

非常感谢任何帮助。提前致谢。

最佳答案

你似乎让事情变得不必要地复杂化了。你说:

I don't want to recreate new instances of DataBaseHelper in each new activity. From what I have seen, the best way to do this is to implement android.os.parcelable, which is fine.

但是从 Parcel 恢复 DataBaseHelper 对象确实会创建 DataBaseHelper 类的新实例;这只是比创建新的 DataBaseHelper 更困难的方法。

无论如何,虽然您没有在此处复制并粘贴错误消息,但我想我知道您收到了什么错误:这并不是说您的 DataBaseHelper 类不包含正确的构造函数;而是您的 DataBaseHelper 类不包含正确的构造函数。确实如此。这是因为父类(super class) 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com