3

Databaseデータベースが 1 つあり、データベースの管理に役立つクラスを作成しましたprivate static class DbHelper extends SQLiteOpenHelper

このデータベースは、4 つの異なるアクティビティからアクセスされます。

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();

2番:

string.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

DB からのデータの読み込みには Loader を使用します。バックグラウンド クラスを UI 要素で乱雑にしないでください

onCreateLoader(.. 
   //you can start progress

onLoadFinished(..
   // you can stop it

また、推奨されるバックグラウンド スレッドからデータを読み取ります。

于 2012-08-24T18:36:05.350 に答える
1

このメソッドは、アプリを最初に実行したときではなく、 oronCreate(SQLiteDatabase)を初めて呼び出したとき (つまり、最初に開いたとき) にのみ呼び出されます (もちろん、単純にデータベースを開いて閉じることで、最初にこれが発生する可能性があります)。getReadableDatabase()getWritableDatabase

現在実行中のアクティビティに progressDialog を表示する必要があるため、 Application コンテキストが機能するかどうかはわかりません。

データベースが最初にアクセスされたときにプログレス バーを正確に表示しようとする代わりに、現在のアクティビティがデータベース自体にアクセスするたびにプログレス バーを表示します。そうすれば、データベースへの最初のアクセスは、通常のアクセスによってマスクされます。

すべての DB アクセスに対してプログレス バーを表示したくない場合は、データベースを開いたり閉じたりして、開く前にアクティビティにプログレス バーを表示させ、閉じるときにプログレス バーを削除することができます (実行しないでください)。 let onCreate()run以外のデータベースに関するもの)。

データベース構造が非常に大きい場合を除き、プログレス バーも表示されない可能性があります。テーブルの作成にそれほど時間はかかりません。

于 2012-08-24T17:01:02.750 に答える
0

SQLiteOpenHelper にはこれらのメソッドが含まれていないため (Activity とは異なり)、アプリケーションのコンテキストにアクセスできません。

私のアドバイスは、DbHelper クラスを使用してデータベースをセットアップし、SQL トランザクションを管理することです。そのコンストラクターにコンテキスト オブジェクトを取得させ、Activity を拡張するクラス内でそのインスタンスを作成し、コンテキストをコンストラクターに渡します。

また、アクティビティと sqlliteOpenHelper の間にデータ アクセス オブジェクト クラスを配置して、データベース オブジェクトのトランザクションの開始、終了、発行を管理することもお勧めします。

于 2012-08-24T17:01:54.533 に答える
0

ユーザーの進行状況を表示するには、別のスレッドで作業を実行する必要があります。そうしないと、データベースの作業が完了するまで GUI がフリーズし、ユーザーは「アクティビティが応答しません。強制終了します」というメッセージを受け取る可能性があります。

クラスを使用Applicationして、データベースが作成されたかどうかに関するグローバル フラグを格納します。

開始アクティビティはすべてこのフラグをチェックし、データベースが初期化されていない場合は を作成しAsyncTask、コンストラクターで db と独自のコンテキストを渡します。AsyncTask次の 3 つの方法があります。

  1. onPreExecute : ここにダイアログを表示します。ダイアログをキャンセル不可にして、ユーザーがスキップできないようにします。
  2. doInBackground : ここにデータベース構築コード。(データベース ヘルパー クラス メソッドを呼び出します)
  3. onPostExecute : ダイアログを閉じます。これで、ユーザーはアクティビティを操作できます。
于 2012-08-24T17:19:20.150 に答える