【问题标题】:Android get context in databaseAndroid在数据库中获取上下文
【发布时间】:2012-08-24 16:45:23
【问题描述】:

我有一个数据库,我创建了一个 Database 类,其中包含一个 private 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);
        }
    }
}

使用上面的代码,我在new loadDB().execute(); 中收到此错误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).

【问题讨论】:

  • 不,您不能在doInBackground() 方法中触摸与GUI 相关的任何内容。覆盖 onPreExecute() 并调用 ProgressDialog.show()
  • @wingman 好的。做到了。但是我应该打电话给new loadDB().execute();吗?
  • loadDB 之外的任何地方,基本上在您活动的onStart() 中。
  • @wingman 做新的 loadDB().execute();在我的Database class it gives this error: onCreate(SQLiteDatabase db) 中没有可以访问数据库类型的封闭实例。必须使用数据库类型的封闭实例来限定分配(例如,x.new A(),其中 x 是数据库的实例)。` 在我的主类/活动的 onCreate(Bundle savedInstanceState) 中执行 new loadDB().execute(); 会给出错误:loadDB cannot be resolved to a type .感谢您的帮助

标签: android database android-context


【解决方案1】:

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

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之前调用了构造函数。

【讨论】:

  • 我的构造函数不是这样的。请查看我更新的问题
  • 谢谢。现在问题出在new loadDB().execute(); 上。在我的Database 类的onCreate(SQLiteDatabase db) 中执行new loadDB().execute(); 它给出了这个错误: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). 在我的主要类/活动的onCreate(Bundle savedInstanceState) 中执行new loadDB().execute(); 它给出了错误:loadDB cannot be resolved to a type
  • 您的内部类需要对外部类的引用。在这里阅读:stackoverflow.com/questions/633585/…
  • @cskoalo 谢谢。它工作正常,但现在它不显示ProgressDialog 如果您有时间,请在此处粘贴代码pastebin.com/M5pJc6fy
【解决方案2】:

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

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

与其尝试在第一次访问数据库时精确显示进度条,不如在访问数据库本身的任何时候显示当前活动。这样一来,对数据库的首次访问就会被对它的常规访问所掩盖。

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

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

【讨论】:

    【解决方案3】:

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

    onCreateLoader(.. 
       //you can start progress
    
    onLoadFinished(..
       // you can stop it
    

    另外你从推荐的后台线程读取数据。

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • 您是否可以猜到,应用程序期待一个数据库实例来执行,您是否在调用活动中声明了一个数据库实例?然后调用 loaddb() 反对?
      • 抱歉,没听懂。我应该在调用数据库的活动中执行Database db= new Database(this); new loadDB().execute(); db.open(); 之类的操作吗?
      • 在执行前尝试打开数据库
      【解决方案5】:

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

      使用Application 类存储一个关于数据库是否已创建的全局标志。

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

      1. onPreExecute :在此处显示您的对话框。使对话框不可取消,因此用户不能跳过它。
      2. doInBackground :此处的数据库构建代码。 (调用数据库助手类方法)
      3. onPostExecute :关闭对话框。现在用户可以与 Activity 交互了。

      【讨论】:

      • 我遵循了您的建议,但遇到了错误。请查看我更新的问题
      猜你喜欢
      • 2014-01-30
      • 2020-05-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多