web-dev-qa-db-fra.com

Comment utiliser une classe de contrat dans Android?

Je suis un peu confus parce que je ne sais pas comment interpréter le didacticiel ici: http://developer.Android.com/training/basics/data-storage/databases.html#DbHelper =

Jusqu'à présent, mon code ressemble à ceci:

public final class DatabaseContract {
// To prevent someone from accidentally instantiating the contract class,
// give it an empty constructor.
public DatabaseContract() {}

public static abstract class Table1 implements BaseColumns {
    public static final String TABLE_NAME       = "nameOfTable";
    public static final String COLUMN_NAME_COL1 = "column1";
    public static final String COLUMN_NAME_COL2 = "column2";
    public static final String COLUMN_NAME_COL3 = "column3";
}

public class DatabaseHelper extends SQLiteOpenHelper {
    // If you change the database schema, you must increment the database version.
    public static final  int    DATABASE_VERSION   = 1;
    public static final  String DATABASE_NAME      = "database.db";
    private static final String TEXT_TYPE          = " TEXT";
    private static final String COMMA_SEP          = ",";
    private static final String SQL_CREATE_ENTRIES = "CREATE TABLE " +
            Table1.TABLE_NAME + " (" +
            Table1._ID + " INTEGER PRIMARY KEY," +
            Table1.COLUMN_NAME_COL1 + TEXT_TYPE + COMMA_SEP +
            Table1.COLUMN_NAME_COL2 + TEXT_TYPE + COMMA_SEP +
            Table1.COLUMN_NAME_COL3 + TEXT_TYPE + COMMA_SEP + " )";
    private static final String SQL_DELETE_ALL_ENTRIES = "DROP TABLE IF EXISTS " + Table1.TABLE_NAME;

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    // Method is called during creation of the database
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(SQL_CREATE_ENTRIES);
    }

    // Method is called during an upgrade of the database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(DatabaseHelper.class.getName(), "Upgrading database from version " + oldVersion + " to " + newVersion + ", which will destroy all old data");

        db.execSQL(SQL_DELETE_ALL_ENTRIES);
        onCreate(db);
    }
}
}

L'ai-je bien interprété ou les 6 premières variables de la classe Helper sont-elles extérieures à la classe Contract? Ou la classe d'assistance ne devrait-elle pas être une classe interne de la classe de contrat?

J'espère que vous pourrez m'aider

29
maysi

Votre contrat définit essentiellement votre base de données et la façon dont les gens doivent interagir avec elle via le fournisseur de contenu.

Une classe de contrat définit des constantes qui aident les applications à travailler avec les URI de contenu, les noms de colonne, les actions d'intention et d'autres fonctionnalités d'un fournisseur de contenu. Les classes de contrat ne sont pas incluses automatiquement avec un fournisseur; le développeur du fournisseur doit les définir, puis les mettre à la disposition des autres développeurs.

Cela dit, vous n'avez pas nécessairement besoin d'un fournisseur de contenu pour utiliser une classe Contract. Mon exemple contient des constantes utilisées par le fournisseur de contenu (les parties MIME et URI). Si vous n'utilisez pas de fournisseur de contenu, vous n'avez pas besoin de ces sections.

J'aime à considérer la classe de contrat comme un schéma de base de données, ou en d'autres termes quelque chose qui définit la configuration de votre base de données. Vous remarquerez peut-être que tout dans la classe de contrat est déclaré statique. C'est parce que vous n'instancierez jamais une classe Contract, mais seulement en vous référant aux constantes qui y sont définies. Vous pouvez voir dans mon exemple que ma classe Contract a juste un tas de variables finales statiques déclarées. Cette classe de contrat peut être son propre fichier, par exemple mon fichier s'appelle TransitContract.Java.

Supposons par exemple que vous vouliez changer le nom d'une de vos colonnes. Plutôt que de modifier plusieurs fichiers, il vous suffit de modifier la valeur de la colonne dans la classe de contrat. Vous n'effectuez aucun type de calcul à l'intérieur de la classe de contrat.

La classe SQLLiteOpenhelper, d'autre part, a été fournie par Google pour faciliter le travail avec les bases de données. C'est là que vous implémentez les méthodes qui créent et configurent la base de données initiale. Voir http://developer.Android.com/reference/Android/database/sqlite/SQLiteOpenHelper.html . Après avoir implémenté ces méthodes, il vous suffit d'instancier une instance de votre classe d'assistance, puis d'appeler helperClassInstance.getWriteableDatabase () (ou getReadableDataBase ()), puis votre classe d'assistance se charge automatiquement de créer une nouvelle base de données si nécessaire, ou retourner celui qui existe déjà, etc.

Cet assistant est généralement implémenté en tant que classe interne, mais pourrait être sa propre classe autonome. C'est comme vous voulez l'implémenter.

Je recommande fortement de regarder l'exemple du Bloc-notes que Google fournit car il a un assez bon exemple de la façon dont vous pouvez éventuellement configurer une classe de contrat. Veuillez noter qu'ils utilisent également un fournisseur de contenu. Si vous souhaitez en savoir plus sur les fournisseurs de contenu, je vous recommande d'en lire davantage sur http://developer.Android.com/guide/topics/providers/content-provider-basics.html . Il va beaucoup plus en profondeur sur les fournisseurs de contenu et les classes de contrat.

Voici un exemple utilisant votre code. Je n'ai pas réellement testé ce code, il pourrait donc contenir des erreurs. Comme vous pouvez le voir, vous pouvez instancier votre assistant db partout où vous le jugez nécessaire. Dans cet exemple, je le fais dans onCreate de l'activité principale, mais en réalité, c'est une mauvaise pratique.

DatabaseContract.Java

public final class DatabaseContract {

    public static final  int    DATABASE_VERSION   = 1;
    public static final  String DATABASE_NAME      = "database.db";
    private static final String TEXT_TYPE          = " TEXT";
    private static final String COMMA_SEP          = ",";

    // To prevent someone from accidentally instantiating the contract class,
    // give it an empty constructor.
    private DatabaseContract() {}

    public static abstract class Table1 implements BaseColumns {
        public static final String TABLE_NAME       = "nameOfTable";
        public static final String COLUMN_NAME_COL1 = "column1";
        public static final String COLUMN_NAME_COL2 = "column2";
        public static final String COLUMN_NAME_COL3 = "column3";


        public static final String CREATE_TABLE = "CREATE TABLE " +
                TABLE_NAME + " (" +
                _ID + " INTEGER PRIMARY KEY," +
                COLUMN_NAME_COL1 + TEXT_TYPE + COMMA_SEP +
                COLUMN_NAME_COL2 + TEXT_TYPE + COMMA_SEP +
                COLUMN_NAME_COL3 + TEXT_TYPE + " )";
        public static final String DELETE_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;
    }
}

DatabaseHelper.Java

public class DatabaseHelper extends SQLiteOpenHelper {    
    public DatabaseHelper(Context context) {
        super(context, DatabaseContract.DATABASE_NAME, null, DatabaseContract.DATABASE_VERSION);
    }

    // Method is called during creation of the database
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DatabaseContract.Table1.CREATE_TABLE);
    }

    // Method is called during an upgrade of the database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(DatabaseContract.Table1.DELETE_TABLE);
        onCreate(db);
    }
}

MainActivity.Java

public class MainActivity extends Activity {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); 

        // Create new helper
        DatabaseHelper dbHelper = new DatabaseHelper(getContext());
        // Get the database. If it does not exist, this is where it will
        // also be created.
        SQLiteDatabase db = dbHelper.getWriteableDatabase();

        // Create insert entries
        ContentValues values = new ContentValues();
        values.put(DatabaseContract.Table1.COLUMN_NAME_COL1, "value1");
        values.put(DatabaseContract.Table1.COLUMN_NAME_COL2, "value2");
        values.put(DatabaseContract.Table1.COLUMN_NAME_COL3, "value3");

        // Insert the new row, returning the primary key value of the new row
        long newRowId;
        newRowId = db.insert(
                 DatabaseContract.Table1.TABLE_NAME,
                 null,
                 values);
    }
}

Et mon exemple

public final class TransitContract {
    public static final String AUTHORITY = "com.example.TransitProvider";
    public static final String SCHEME = "content://";
    public static final String SLASH = "/";
    public static final String DATABASE_NAME = "transit.db"; 

    /* An array list of all the SQL create table statements */
    public static final String[] SQL_CREATE_TABLE_ARRAY = {
        Agency.CREATE_TABLE,
        CalendarDates.CREATE_TABLE,
        Calendar.CREATE_TABLE,
        Routes.CREATE_TABLE,
        Shapes.CREATE_TABLE,
        Stops.CREATE_TABLE,
        StopTimes.CREATE_TABLE,
        Trips.CREATE_TABLE
    };

    /**
     * Array of resource ids for each GTFS data file that will be loaded into 
     * database
     */
    public static final int[] RAW_IDS = {
        R.raw.agency,
        R.raw.calendar_dates,
        R.raw.calendar,
        R.raw.routes,
        R.raw.shapes,
        R.raw.stops,
        R.raw.stop_times,
        R.raw.trips,
    };

    /* Do not allow this class to be instantiated */
    private TransitContract() {}

    public static final class Agency implements BaseColumns {
        /* Do not allow this class to be instantiated */
        private Agency() {}

        public static final String TABLE_NAME = "Agency";

        public static final String KEY_AGENCY_ID = "AgencyId";

        public static final String KEY_NAME = "Name";

        public static final String KEY_URL = "Url";

        public static final String KEY_TIMEZONE = "Timezone";

        public static final String KEY_LANG = "Language";

        public static final String KEY_PHONE = "PhoneNumber";

        public static final String KEY_FARE_URL = "FareUrl";

        /*
         * URI definitions
         */

        /**
         * The content style URI
         */
        public static final Uri CONTENT_URI = Uri.parse(SCHEME + AUTHORITY + SLASH + TABLE_NAME);

        /**
         * The content URI base for a single row. An ID must be appended.
         */
        public static final Uri CONTENT_ID_URI_BASE = Uri.parse(SCHEME + AUTHORITY + SLASH + TABLE_NAME + SLASH);

        /**
         * The default sort order for this table
         */
        public static final String DEFAULT_SORT_ORDER = KEY_AGENCY_ID + " ASC";

        /*
         * MIME type definitions
         */

        /**
         * The MIME type of {@link #CONTENT_URI} providing rows
         */
        public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + 
                                                "/vnd.com.marylandtransitcommuters.agency";

        /**
         * The MIME type of a {@link #CONTENT_URI} single row
         */
        public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + 
                                                "/vnd.com.marylandtransitcommuters.agency";

        /**
         * SQL Statement to create the routes table
         */
        public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " ("
                                                  + _ID + " INTEGER PRIMARY KEY,"
                                                  + KEY_AGENCY_ID + " TEXT,"
                                                  + KEY_NAME + " TEXT,"
                                                  + KEY_URL + " TEXT,"
                                                  + KEY_TIMEZONE + " TEXT,"
                                                  + KEY_LANG + " TEXT," 
                                                  + KEY_PHONE + " TEXT,"
                                                  + KEY_FARE_URL + " TEXT"
                                                  + ");";

        /**
         * SQL statement to delete the table
         */
        public static final String DELETE_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME;

        /**
         * Array of all the columns. Makes for cleaner code
         */
        public static final String[] KEY_ARRAY = {
            KEY_AGENCY_ID,
            KEY_NAME,
            KEY_URL,
            KEY_TIMEZONE,
            KEY_LANG,
            KEY_PHONE,
            KEY_FARE_URL
        };
    } 
96
btse