0

我有一个 SQLite 数据库,它与扩展 Activity 的主类位于一个单独的类中。

我注意到有两种设置数据库的方法。一种方法是将它放在主 Activity 类中,无论是在类中还是作为嵌套的子类。第二种方法是将它放在单独的类中。

单独的类看起来更好,但是有一个缺点。每次你想做某事时,你都必须在主活动类中创建它的一个实例。我读到在 Android 中实例化对象很昂贵,应该避免。

尽管如此,我还是宁愿将数据库作为一个单独的类。实例化对象的成本是否足以使将数据库放在同一个类中更划算?

SQLite 数据库的单独类的示例:不完整的伪代码

public class SQLiteDB {
   private static class DbHelper extends SQLiteOpenHelper{
      // db helper methods
   }

// methods for DB, like get, set, and others
public void openDatabase(){  }
public void closeDatabse(){  }
public void insertRecord(String record){  }
}

主要活动中的示例使用:incompete psudo-code

public class Main extends Activity{

// every time I want to use it I must instantiate an object for the database class

// many instances of SQLiteDB object created, garbage collector works hard

SQLiteDB mDatabase = new SQLiteDB();

openDatabase();

insertRecord("insert this");

closeDatabase();

}
4

3 回答 3

2

SQLite database in separate class vs. in same class, which is better?

This is very comprehensive question and it depends on more factors(type of application, personal requirements, how you'll deal with db etc.). Somebody can prefer to place database as inner class and someone as separated class. Problem is that many developers are trying to "stick" as much code as possible into one class and maybe they "fear" to create a little more classes. I don't know that exactly. I mentioned that only as my personal note.

But let's back to your question. What is better?

I think that approach with separeted class. You should let your Activity classes only "Activity classes" > only for creating and dealing with UI. Application appearance should be separated from application logic. If you'll follow this "rule" your code will become more clean and human-readable(if someone else will look at your code he shouldn't be completely lost). It's not a shame to have 20 purely written classes as to have all stuff sticked in one class(like a pig).

however there is one disadvantage. You have to create an instance of it in the main activity class every time you want to do something. I read that instantiating objects in Android is expensive and should be avoided.

Did you think about an usage of Singleton? This design pattern is worth to think about it. You will always have only one instance that have many benefits e.q. no waste of memory. I have only good experiences with Singleton. Therefore i recommend you to try and use it.

Example:

private static SQLiteOpenHelper instance;

public static SQLiteOpenHelper getInstance(Context mContext) {
   if (instance == null) {
      instance = new SQLiteOpenHelperImplementation(mContext);
   }
   return instance;
}

And at the end i give you a few suggestions:

  • Everytime you'll work with cursors, databases etc. release / close them immediately after work is done. This can solve many exceptions related to SQLiteDatabase and Cursor

  • An usage of synchronized blocks and methods is pretty good practise in the case of concurrent programming to avoid many problems

  • If you have more than one table in database i suggest you create "serving" class for each table that will wrap CRUD operations and specific methods of the table

  • Before Activity is destroyed, check and release all sources which are not already released.

于 2013-03-31T23:03:33.927 回答
0

这将是个人品味的问题。

然而,我发现高效和干净的是创建一个扩展 SQLiteOpenHelper 的类。在本课程中,您最终将编写 SQL 代码来创建表并将方法编写为存储过程。

该类看起来像这样:

public class DatabaseInterface extends SQLiteOpenHelper {

// Database version
private static final int DATABASE_VERSION = 1;
public DatabaseInterface(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);

}
//in your oncreate you will write the queries to create your tables
@Override
public void onCreate(SQLiteDatabase db) {

    String CREATE_NEWS = "CREATE TABLE News(id INTEGER)";

    db.execSQL(CREATE_NEWS);
}

// upgrading tables
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    // drop tables if exist
    db.execSQL("DROP TABLE IF EXSIST " + NEWS);
    // recreate tables
    onCreate(db);

}

考虑我们有一个 News obj,它接受 1 个参数作为它的构造函数,您的存储过程可能看起来像这样:

public ArrayList<News> getNews() {
    ArrayList<News> mNewes = new ArrayList<News>();
    SQLiteDatabase db = null;
    Cursor cursor = null;

    try {
        String sQry = "SELECT * FROM " + NEWS;
        db = this.getWritableDatabase();
        cursor = db.rawQuery(sQry, null);

        if (cursor.moveToFirst()) {
            do {
                mNewes.add(new News(cursor.getInt(0)));

            } while (cursor.moveToNext());
        }
    } catch (SQLiteException e) {
        Log.e("SQLite - getNewes", e.getMessage());
        return null;
    } finally {
        cursor.close();
        db.close();
    }

    return mNewes;
}

在上述方法中,您获取并打开应用程序数据库,对其进行查询,预测任何 sql 错误,然后关闭数据库。这样做可以确保您永远不会打开任何您不需要/不使用的资源。

我已经在两个目前在市场上销售的应用程序中使用了这种方法,它运行得相当快,对我为存储过程创建的方法进行了数百次调用

于 2013-01-31T00:44:56.053 回答
0

我更喜欢你在这里给出的解决方案。主要优点是您可以轻松地从应用程序中的任何 Activity(或其他类)访问数据库。为了解决每次使用数据库都创建一个新实例的问题,可以改为在 中创建一个实例onCreate(),在 Activity 处于活动状态时随意使用数据库,最后在 中关闭数据库onDestroy()

于 2013-01-31T00:42:49.360 回答