3

我有一个数据库,我创建了一个Databaseprivate static class DbHelper extends SQLiteOpenHelper来帮助我管理我的数据库。

这个数据库是从四个不同的活动中访问的。

我有这个public void onCreate(SQLiteDatabase db),它是创建我的数据库表并向这些表添加值的原因。由于程序仅在用户第一次运行应用程序时进入此处,因此我想创建一个ProgressDialog.

这就是我所拥有的:

Override
public void onCreate(SQLiteDatabase db) {

    ProgressDialog progresso = ProgressDialog.show(context, "Info", "Loading DB" );
    // Code to create the tables and add the values
    progress.dismiss();
}

有2个问题。

第一的:

由于可以从 4 个不同的活动中访问它,我如何获取上下文?制造:

Context context = getAplicationContext();

第二:

为什么我不能使用 strings.xml 中的字符串?我不能这样做:

ProgressDialog progresso = ProgressDialog.show(context, getString(R.string.driProgressTitle), getString(R.string.driProgressMessage) );

更新

public class Database {
    ProgressDialog progresso;
    private DbHelper DBHelper;
    private final Context Context;
    private SQLiteDatabase BaseDados;

    private static class DbHelper extends SQLiteOpenHelper {

        public DbHelper(Context context) {
            super(context, BD_NAME, null, BD_VERSION);
            // TODO Auto-generated method stub
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

        // Whanted to show here the progress dialog
        new loadDB().execute();

        // Creates the table and adds the values

        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVesion) {
            db.execSQL("DROP TABLE IF EXISTS MYTABLE");
            onCreate(db);
        }

    }

    public Database(Context c) {
        Context = c;
    }

    public Database open() throws SQLException {
        DBHelper = new DbHelper(Context);
        BaseDados = DBHelper.getWritableDatabase();
        return this;
    }

    public void close() {
        DBHelper.close();
    }

    public Cursor getData(int tipo, long groupId, String query[]) {
        // Performs the querys to my database
    }
    return null;
}

    public class loadDB extends AsyncTask<Void, Void, Integer> {

        @Override
        protected Integer doInBackground(Void... params) {
            progresso = ProgressDialog.show(Context, Context.getString(R.string.ProgressTitle), Context.getString(R.string.ProgressMessage) );
            return 1;
        }

        @Override
        protected void onPostExecute(Integer result) {
            progresso.dismiss();
            super.onPostExecute(result);
        }
    }
}

使用上面的代码,我No enclosing instance of type Database is accessible. Must qualify the allocation with an enclosing instance of type Database (e.g. x.new A() where x is an instance of Database).new loadDB().execute();.

4

5 回答 5

8

你不能从构造函数访问上下文吗?

SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)

SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) 

编辑:

你的代码:

public DbHelper(Context context) {
        super(context, BD_NAME, null, BD_VERSION);
        // TODO Auto-generated method stub
    }

此时您可以访问上下文..您可以执行一些操作,例如添加一个名为 context 的字段,然后执行以下操作:

Context context;
public DbHelper(Context context) {
        super(context, BD_NAME, null, BD_VERSION);
        // TODO Auto-generated method stub
        this.context = context;
    }

现在,您可以在课堂上的任何地方访问上下文?假设在 onCreate 之前调用了构造函数。

于 2012-08-24T17:06:50.983 回答
1

使用 Loader 从 DB 读取数据。不要用 UI 的东西弄乱背景类

onCreateLoader(.. 
   //you can start progress

onLoadFinished(..
   // you can stop it

您还可以从推荐的后台线程读取数据。

于 2012-08-24T18:36:05.350 回答
1

onCreate(SQLiteDatabase)方法仅在您第一次调用getReadableDatabase()or时被调用getWritableDatabase(即第一次打开时),而不是在应用程序第一次运行时调用(当然,您可以首先通过简单地打开数据库然后关闭它来实现)。

我不确定给它应用程序上下文是否会起作用,因为progressDialog 需要显示在当前运行的活动中。

与其尝试在第一次访问数据库时精确显示进度条,不如让您当前的 Activity 在它访问数据库本身的任何时候显示一个。这样,对数据库的第一次访问就会被定期访问所掩盖。

如果您不想显示所有数据库访问的进度条,那么您可以再次打开和关闭数据库并让您的活动在打开它之前显示一个进度条,并在您关闭它时删除进度条(不做数据库中的任何内容,除了让onCreate()运行)。

除非您的数据库结构非常大,否则您可能甚至看不到进度条。创建表不需要很长时间。

于 2012-08-24T17:01:02.750 回答
0

要显示用户进度,您必须在单独的线程中运行您的工作,否则 GUI 将冻结,直到数据库工作完成,并且用户可能会收到“活动没有响应,强制关闭”消息。

使用Applicationclass 来存储有关是否已创建数据库的全局标志。

任何开始的活动都会检查这个标志,如果数据库没有被初始化,它会创建一个AsyncTask,在构造函数中传递 db 和它自己的上下文。AsyncTask将有三种方法:

  1. onPreExecute :在此处显示您的对话框。使对话框不可取消,因此用户无法跳过它。
  2. doInBackground :这里的数据库构建代码。(调用数据库助手类方法)
  3. onPostExecute :关闭对话框。现在用户可以与 Activity 交互。
于 2012-08-24T17:19:20.150 回答
0

您无法访问应用程序的上下文,因为 SQLiteOpenHelper 不包含这些方法(与 Activity 不同)

我对您的建议是使用 DbHelper 类来设置数据库并管理任何 sql 事务。让它的构造函数获取一个上下文对象,然后在扩展 Activity 的类中创建它的实例,将上下文传递给构造函数。

在活动和 sqlliteOpenHelper 之间放置一个数据访问对象类也是一种很好的做法,它也可以管理数据库对象的打开、关闭和发出事务

于 2012-08-24T17:01:54.533 回答