0

在我的应用程序中,我有一个内容提供者,它使用数据库来提供所提供的内容。第一次创建数据库时,需要从 Json 文件的原始内容中填充。我的想法是在我的 SQLiteOpenHelper 子类的 onCreate 处触发数据库的填充。这工作正常,但我不确定在应用程序第一次运行时如何处理应用程序和内容提供者之间的通信。基本上我想在数据库被填满时显示某种闪屏。然而,应用程序如何获得通知

  1. 第一次运行时,内容提供者正忙于填充数据库
  2. 内容提供商已准备就绪

当然,我可以通过使用每个数据集调用内容提供者来从应用程序中填充数据库,但我更愿意在内容提供者的范围内进行,这样应用程序就不必处理 json 文件的读取等。除了设计偏好它还将使内容提供者能够更有效地填充数据库,因为它会同时拥有整个数据集。我有一种感觉,这是不可能的,但我希望我错过了一些简单的观点。

任何如何实现这一目标的建议将不胜感激。

谢谢

马丁

4

1 回答 1

0

当使用内容提供者时,我会假设您使用 DBHelper 类来管理数据库的创建。下面是来自 android notes 示例项目的代码。

这显示了 DBHelper 构造函数如何足够智能地确定数据库之前是否已创建。在 createDatabase 方法中,我随后会调用一个方法来预填充数据库,如您所说的 json 文件。

问题是这实际上不允许您与 Activity 进行通信,即您的数据库尚未初始化。

一种想法可能是您使用 SharedPreferences 来存储您已填充数据库的事实。然后,您可以在启动时检查活动中的 sharedPreference,调用内容提供者来填充数据库,然后存储您已经完成此任务的共享首选项。

请注意,如果您例如从 android 设置菜单中删除数据,我不确定 sharedPreferences 是否保持与数据库相同的状态。你需要检查一下。

http://code.google.com/p/android-notes/source/browse/trunk/src/com/bitsetters/android/notes/DBHelper.java?r=10

public class DBHelper {

private static final String DATABASE_NAME = "notes";
private static final String TABLE_DBVERSION = "dbversion";
private static final String TABLE_NOTES = "notes";
private static final int DATABASE_VERSION = 1;
private static String TAG = "DBHelper";
Context myCtx;

private static final String DBVERSION_CREATE = 
    "create table " + TABLE_DBVERSION + " ("
            + "version integer not null);";

private static final String NOTES_CREATE =
    "create table " + TABLE_NOTES + " ("
        + "id integer primary key autoincrement, "
        + "note text, "
        + "lastedit text);";

private static final String NOTES_DROP =
    "drop table " + TABLE_NOTES + ";";

private SQLiteDatabase db;
/**
 * 
 * @param ctx
 */
public DBHelper(Context ctx) {
    myCtx = ctx;
            try {
                    db = myCtx.openOrCreateDatabase(DATABASE_NAME, 0,null);

                    // Check for the existence of the DBVERSION table
                    // If it doesn't exist than create the overall data,
                    // otherwise double check the version
                    Cursor c =
                            db.query("sqlite_master", new String[] { "name" },
                                            "type='table' and name='"+TABLE_DBVERSION+"'", null, null, null, null);
                    int numRows = c.getCount();
                    if (numRows < 1) {
                            CreateDatabase(db);
                    } else {
                            int version=0;
                            Cursor vc = db.query(true, TABLE_DBVERSION, new String[] {"version"},
                                            null, null, null, null, null,null);
                            if(vc.getCount() > 0) {
                                vc.moveToFirst();
                                version=vc.getInt(0);
                            }
                            vc.close();
                            if (version!=DATABASE_VERSION) {
                                    Log.e(TAG,"database version mismatch");
                            }
                    }
                    c.close();


            } catch (SQLException e) {
                    Log.d(TAG,"SQLite exception: " + e.getLocalizedMessage());
            } finally {
                    db.close();
            }
}

private void CreateDatabase(SQLiteDatabase db)
{
            try {
                    db.execSQL(DBVERSION_CREATE);
                    ContentValues args = new ContentValues();
                    args.put("version", DATABASE_VERSION);
                    db.insert(TABLE_DBVERSION, null, args);

                    db.execSQL(NOTES_CREATE);
                    // Populate with data
                    populateDataBaseFromFile();// There are probably better ways to do this.
                    setSharedPreferenceYouPopulatedDB();
            } catch (SQLException e) {
                    Log.d(TAG,"SQLite exception: " + e.getLocalizedMessage());
            } 
}

就我个人而言,除非你真的需要,否则我不会打扰启动画面。

另一个想法可能是:

  1. 在 db helper 中编写一个方法来确定您的表是否存在。如果不是,则返回 false。
  2. 在启动活动中,使用调用 DBHelper 测试方法的请求调用 ContentProvider。
  3. 如果为 false,则显示启动屏幕,然后调用 Content Provider 来填充 DB。
  4. 如果属实,则照常进行。
于 2012-09-01T18:15:46.377 回答