7

db オブジェクトの単一インスタンスを使用する databaseprovider クラスを作成しました。オブジェクトはメイン アクティビティで作成され、onDestroy メソッドで閉じられます。これは問題ないようです (ただし、シミュレートできない一部のユーザーのデバイスでは、db が既に閉じられている、または db が開いていないなどのエラーが発生します)。

コンテンツ ダウンロード用のサービスをアプリケーションに追加したいのですが、このサービスはスケジューラで実行できるため、db オブジェクトの単一インスタンスが機能しないと考えられます。サービスに別のオブジェクトを使用する必要がありますか?一貫性の問題が発生しますか? 最善の方法を教えてください。

データベースプロバイダークラスの例:

public class DatabaseProvider {
private static DatabaseHelper helperWriter;
public static SQLiteDatabase db_global;
public DatabaseProvider(Context c) {
    helperWriter = DatabaseHelper.getHelper(c, true);
}

private static SQLiteDatabase getDB() {     

    if(db_global == null)           
        db_global = helperWriter.getWritableDatabase();
    else if(!db_global.isOpen()) {
        try {
            db_global.close();
        }
        catch(Exception ex) {
            ex.printStackTrace();
        }
        db_global = helperWriter.getWritableDatabase();
    }

    return db_global;
}

public String GetVersion() {
    SQLiteDatabase db = getDB();
    Cursor c = db.query(DatabaseHelper.PARAMETER_TABLE_NAME, new String[] {"VALUE"}, "KEY='Version'", null, null,null,null);
    String version = "";
    if(c.moveToNext())
    {
        version = c.getString(0);           
    }
    else
        version = "0";
    c.close();

    return version;
}

public long UpdateVersion(String value) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(DatabaseHelper.PARAMETER_COLUMN_VALUE, value);
    SQLiteDatabase db = getDB();   
    long r = db.update(DatabaseHelper.PARAMETER_TABLE_NAME, initialValues, "KEY='Version'", null);
    if(r <= 0)
        r = helperWriter.AddParameter(db, "Version", value);
    //db.close();   
    return r;
}   

public void CloseDB() {
    if (db_global != null)
        db_global.close();
    db_global = null;
    helperWriter.close();
}
 }

4

2 に答える 2

1

これが役立つかどうかはわかりませんが...

アプリがクラッシュした場合に備えて、onDestroy()に依存することはできません。Androidは、アプリを終了した場合でも、アプリをRAMに保持する場合があります。また、サブアクティビティを使用している場合、アプリの使用中にメインアクティビティが破棄される可能性があります。また、再作成することもできます。

DBを開き、DBに対して処理を実行してから、同じ関数内でDBを閉じる呼び出しを行う方がよい場合があります。サービスを使用している場合、それは実際に物事を助けるかもしれません。また、管理コードがなくても、DBを開いたり、さまざまな場所からさまざまな場所に一度にアクセスしたりできる状況が必要かどうかもわかりません。

于 2012-09-20T18:32:22.427 に答える
0

いくつかの質問があります。

A)

(ただし、次のようなエラーが発生します:dbはすでに閉じられているか、シミュレートできない一部のユーザーデバイスでdbが開いていません)。... アクティビティを開始し、AsyncTask でコンテンツといくつかのデータベース操作を更新します。更新の進行中に戻って、同じアクティビティを再度開始します。

これらのエラーを回避するために、[Loader][1]? これは、s に関するコールバック ベースのフレームワークContentProviderです。


B)

コンテンツをダウンロードするためのサービスをアプリケーションに追加すると、このサービスはスケジューラで実行できるため、db オブジェクトの単一インスタンスが機能しないと考えられます。サービスに別のオブジェクトを使用する必要がありますか?一貫性の問題が発生しますか?

このWeb サイトの@commonsware によるこの投稿でServiceは、長時間実行されるタスクには使用しないことを提案しています。代わりにAlarmManagerが推奨されます。私自身は、短時間実行されるサービス (オーディオ IO 用) のみを扱ってきました。

于 2012-11-28T05:18:53.320 に答える