2013-07-03 9 views
26

Sono un po 'confuso, perché non so come dovrei interpretare il tutorial qui: http://developer.android.com/training/basics/data-storage/databases.html#DbHelperCome utilizzare una classe di contratto in Android?

Il mio codice fino ad ora sembra che questo:

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

Forse ho interpretato bene o hanno le prime 6 variabili nella classe Helper sono all'esterno nella classe Contract? Oppure la classe Helper non dovrebbe essere una classe interiore della classe di contratto?

Spero che tu mi puoi aiutare

+0

La classe helper non fa parte di businessobjects ... –

+0

quindi dovrei creare un proprio file per la classe Helper? – maysi

risposta

91

tuo contratto definisce fondamentalmente il database e come le persone dovrebbero interagire con esso attraverso il provider di contenuti.

Una classe contratto definisce le costanti che aiutano applicazioni funzionino con l'URI contenuto, i nomi delle colonne, le azioni intenti, e altre caratteristiche di un fornitore di contenuti. Le classi di contratto non sono incluse automaticamente con un fornitore; lo sviluppatore del provider deve definirli e quindi renderli disponibili ad altri sviluppatori.

Detto questo, non è necessario necessariamente un provider di contenuti per utilizzare una classe di contratto. Nell'esempio sono presenti costanti utilizzate dal provider di contenuto (le parti MIME e URI). Se non si utilizza un provider di contenuti, non è necessario queste sezioni.

Mi piace pensare alla classe del contratto come a uno schema di database o, in altre parole, a qualcosa che definisce il modo in cui il database è impostato. Potresti notare che tutto all'interno della classe del contratto è dichiarato come statico. Questo perché non verrà mai istanziata una classe Contract, ma solo facendo riferimento alle costanti definite in essa. Puoi vedere nel mio esempio che la mia classe Contract ha solo un gruppo di variabili finali statiche dichiarate. Questa classe Contract può essere il proprio file, ad es. il mio file si chiama TransitContract.java.

Ad esempio, si desidera modificare il nome di una delle colonne. Anziché apportare modifiche a più file, tutto ciò che devi fare è modificare il valore per la colonna nella classe del contratto. Non stai facendo nessun tipo di lavoro di calcolo all'interno della classe di contratto.

La classe SQLLiteOpenhelper, d'altra parte, è stata fornita da Google per semplificare il lavoro con i database. Qui è dove si implementano i metodi che creano e configura il database iniziale. Vedi http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html. Dopo aver implementato questi metodi, tutto ciò che devi fare è istanziare un'istanza della classe helper, quindi chiamare helperClassInstance.getWriteableDatabase() (o getReadableDataBase()) e quindi la classe helper si occuperà automaticamente della creazione di un nuovo database, se necessario, o restituire quello che esiste già, ecc.

Questo helper è generalmente implementato come classe interna ma potrebbe essere la sua classe autonoma. È comunque che vuoi implementarlo.

Consiglio vivamente di vedere l'esempio del blocco note fornito da Google in quanto ha un buon esempio di come è possibile impostare una classe di contratto. Si noti che usano anche un fornitore di contenuti. Se sei interessato a conoscere i fornitori di contenuti, ti consiglio di leggerne altri al numero http://developer.android.com/guide/topics/providers/content-provider-basics.html. Entra molto più in profondità sui Content Provider e sulle classi Contract.

Ecco un esempio utilizzando il codice. Non ho effettivamente testato questo codice in modo che possa avere errori. Come puoi vedere, puoi istanziare il tuo db helper ovunque tu ritenga necessario. In questo esempio lo faccio nel onCreate della principale attività, ma in realtà questa è una cattiva pratica.

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

E il mio esempio

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 
     }; 
    } 
+0

wow. Grazie mille. ma non conosco ancora le differenze tra la classe di contratto e la classe di aiuto. Cosa devono essere nel contratto e cosa nell'assistente. e sono file di helper e di contratti diversi? – maysi

+0

Ho aggiornato la mia risposta. – btse

+0

WOW !!! grazie. questo è esattamente quello che stavo cercando. – maysi

Problemi correlati