Platforma Android oferă o gamă largă de opțiuni de stocare pentru utilizarea în aplicațiile dvs. În această serie de tutori, vom explora unele dintre facilitățile de stocare a datelor furnizate de SDK-ul Android construind un proiect simplu: un editor de artă ASCII.
Această serie de tutori despre crearea unui editor ASCII simplu de artă este prezentată în patru părți:
Pentru a gestiona o bază de date SQLite în aplicațiile Android, extindem clasa SQLiteOpenHelper. Această clasă va gestiona crearea de baze de date, așa că vom defini structura de date din cadrul acesteia. Creați o clasă nouă în proiectul Android și denumiți-o "ImageDataHelper" sau orice alt nume ales de dvs. Extindeți linia de deschidere a declarației de clasă după cum urmează:
clasa publica ImageDataHelper extinde SQLiteOpenHelper
Adăugați următoarele importuri în partea de sus a clasei:
importați android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.provider.BaseColumns;
În interiorul clasei dvs. de bază de date, creați următoarele variabile pentru a defini proprietățile bazei de date. În primul rând, versiunea bazei de date:
privat static final int DATABASE_VERSION = 1;
Apoi dați baza de date un nume:
static final final static DATABASE_NAME = "asciipics.db";
Pentru a crea un model de bază de date fiabil, avem nevoie de o coloană ID, deci adăugați una folosind BaseColumns constant:
statică finală publică String ID_COL = BaseColumns._ID;
Acest lucru ne dă automat o coloană de cheie primară care va crește automat. Baza de date va conține o singură masă, deci dați-i un nume în continuare:
static final public String TABLE_NAME = "pics";
Tabelul conține două coloane, unul pentru conținutul lucrării de artă ASCII, care va fi un șir de text și unul pentru un nume, care va apărea într-o listă atunci când utilizatorul încearcă să încarce opere de artă salvate. Definiți aceste coloane acum:
static final public static ASCII_COL = "ascii_text"; static final public static CREATED_COL = "pic_creation";
Acum putem defini șirul de creare a bazei de date:
fișierul final final static DATABASE_CREATE = "CREATE TABLE" + TABLE_NAME + "(" + ID_COL + "INTEGER" + "AUTOINCREMENT KEY PRIMARY", + ASCII_COL + TEXT + CREATED_COL + TEXT);
După cum puteți vedea, sintaxa implică SQL standard în acest caz.
Vom folosi o Singleton modelul de proiectare pentru clasa helper de baze de date, pe care probabil că nu l-ați întâlnit în funcție de experiența dvs. Java. Pentru a putea folosi ajutorul bazei de date în mai multe activități, păstrând în același timp eficiența, dorim să limităm aplicația astfel încât să nu poată crea decât o singură instanță a clasei. Adăugați încă câteva variabile de instanță:
static ImageDataHelper static dbInstance; Context privat dbContext;
În loc să folosim direct metoda constructorului, activitățile noastre vor apela o metodă din fabrică pe care o definim pentru a returna o instanță a clasei. Vom folosi prima variabilă aici pentru a stoca instanța, astfel încât aceasta să fie creată doar o singură dată. Variabila de context ne va ajuta să evităm scurgeri de memorie, pe măsură ce vom folosi contextul aplicației, mai degrabă decât contextul pentru activitatea de creare a obiectului ajutorului bazei de date.
După constante, adăugați o metodă constructor la clasa helper de baze de date:
privat ImageDatabase (Context context) super (context, DATABASE_NAME, null, DATABASE_VERSION);
Observați că constructorul este privat, astfel încât codul extern nu va putea să îl numească direct. Acum, adăugați o metodă din fabrică, astfel încât activitățile dvs. să poată crea și accesa singură instanță din această clasă:
public Static ImageDataHelper getInstance (context de context) if (dbInstance == null) dbInstance = nou ImageDataHelper (context.getApplicationContext ()); returnați dbInstance;
Aceasta este o metodă statică, astfel încât să putem accesa aceasta, referindu-ne la clasa în sine, mai degrabă decât printr-o instanță a acesteia. Verificăm dacă instanța de ajutor de bază de date a fost deja creată, apelând doar constructorul dacă nu a făcut-o. Folosim contextul aplicației pentru utilizarea eficientă a memoriei și returnează o instanță a clasei. Veți vedea cum vom instanța această clasă din activități în curând.
Vom executa crearea tabelului bazei de date în onCreate metoda, adăugați-o:
public void onCreate (SQLiteDatabase db) db.execSQL (DATABASE_CREATE);
Aici trecem șirul de creare a tabelei bazei de date. De asemenea, trebuie să furnizăm o metodă de executare atunci când baza de date este modernizată:
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) db.execSQL ("DROP TABLE IF EXISTS pics"); db.execSQL ( "vidate"); onCreate (db);
Distrugem tabelul existent și îl creăm din nou. Dacă doriți să schimbați structura bazei dvs. de date în orice moment, modificați șirul de creare a bazei de date și creșteți numărul versiunii - onUpgrade metoda va executa.
Asta e clasa noastră de asistență pentru baze de date completă. Acum putem crea o instanță a ajutorului bazei de date din Activitatea principală pentru ao folosi când rulează aplicația. În clasa principală a activității, adăugați o variabilă nouă de instanță în partea de sus:
private ImageDataHelper imgData;
În interiorul onCreate , creați o instanță a noii clase:
imgData = ImageDataHelper.getInstance (aceasta);
Observați că folosim numele clasei și metoda din fabrică pentru a returna instanța clasei de asistență a bazei de date, astfel că știm că aplicația ca întreg are cel mult o instanță a clasei.
Rețineți că am inclus un buton Încărcare pentru ca utilizatorii să se încarce în lucrări de artă salvate anterior. În activitatea principală onCreate , ascultați clicurile pe buton:
Butonul loadBtn = (butonul) findViewById (R.id.load_btn); loadBtn.setOnClickListener (aceasta);
Acum, adăugați o nouă secțiune la instrucțiunea condiționată din onClick metodă:
altfel dacă (v.getId () == R.id.load_btn)
Vom adăuga procesarea la acest bloc condițional mai târziu.
Când utilizatorul face clic pe butonul Încărcare, vom lansa o activitate de tip pop-up care va apărea în partea de sus a activității principale. Această nouă activitate va prezenta lista de lucrări de artă salvate în baza de date, permițând utilizatorului să aleagă una de încărcat. Creați o nouă clasă în proiect și denumiți-o "PicChooser" sau un nume alternativ dacă preferați. Deoarece conținutul acestei activități va fi o listă de lucrări, vom folosi a ListActivity, astfel să extindeți linia de declarație de deschidere:
public class PicChooser extinde ListActivity
Adăugați următoarele importuri la clasă:
importă android.app.ListActivity; import șiroid.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import șiroid.view.View; import android.widget.SimpleCursorAdapter; import șiroid.widget.TextView;
Vom folosi baza de date pentru a lista imaginile salvate, deci adăugați variabile de instanță pentru baza de date, ajutor și un cursor pentru a interoga datele:
privat ImageDataHelper picDataHelp; privat SQLiteDatabase savedPictures; Cursor privat picCursor;
Adaugă onCreate metodă:
public void onCreate (bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.load);
Să adăugăm aspectul la care am făcut referire - să adăugăm un nou fișier folderului "res / layout" și să îl denumim "load.xml" pentru a se potrivi cu codul de mai sus. Adăugați o dispunere liniară în noul fișier:
În interiorul layout-ului, adăugați o vizualizare text informativă și o listă de vizualizare pentru a încărca numele de imagini salvate în:
ID-ul de vizualizare a listelor ne va permite să încărcăm date în Java în Java. Adăugați șirul de afișare indicat aici în fișierul XML "res / values / strings":
Alegeți dintre aceste imagini salvate:
Trebuie să definim un aspect pentru fiecare element care va apărea în Vizualizarea listei. Adăugați un fișier de aspect nou în aplicația dvs., numind-o "pic_item.xml" și includeți o dispunere liniară:
Observați că includeți un onClick atribut, specificând numele unei metode pe care dorim să o executăm atunci când utilizatorii fac clic pe elementul de listă în cauză. În interiorul Aspectului liniar, adăugați Vizualizări text pentru ID-ul și șirul de creare pentru imaginea reprezentată:
ID-urile ne vor permite să cartografiam datele din baza de date către aceste Vizualizări.
Înapoi în noua activitate de selectare a imaginilor onCreate , după linia în care ați setat noul aspect, creați instanțe ale bazei de date și ajutor:
picDataHelp = ImageDataHelper.getInstance (aceasta); savedPictures = picDataHelp.getReadableDatabase ();
Utilizăm din nou metoda din fabrică pentru a returna instanța ajutorului bazei de date. Vom folosi un cursor pentru a traversa înregistrările în tabela de baze de date, așa că creați-o acum, interogând totul în tabelul "pics":
picCursor = savedPictures.query ("pics", null, null, null, null, null, null);
Bacsis: În acest tutorial folosim o implementare de bază de date foarte simplă pentru a introduce elementele de bază ale stocării datelor pe Android. Cu toate acestea, pentru aplicațiile mai complexe, ar trebui să consultați utilizarea furnizorilor de conținut pentru operațiile de bază de date. Vedeți această postare folosind Furnizorii de conținut și aceasta pe încărcarea datelor cu Loaders Cursor și Fragmente. Acestea vă vor permite să vă dezvoltați pentru eficiență prin mutarea operațiunilor de încărcare a datelor de pe firul principal al aplicației, dar nivelul de complexitate implicat crește semnificativ în ceea ce privește utilizarea de bază pe care o explorăm aici și este, prin urmare, puțin peste sfera acestei serii.
Pentru fiecare imagine din baza de date, vom lista id-ul și șirul de creare. Vom folosi un adaptor simplu pentru a cartografia aceste elemente la elementele din lista de vizualizare, prezentându-le utilizatorilor pentru a le selecta. Trebuie să definim coloanele tabelului de bază pe care dorim să le afișăm și viziunile pe care le dorim să le mapăm în lista de vizualizare:
String [] coloane = ImageDataHelper.ID_COL, ImageDataHelper.CREATED_COL; int [] vizualizări = R.id.picID, R.id.picName;
Ne putem referi la numele coloanelor folosind constantele publice pe care le-am creat în clasa helper de baze de date. Elementele de aspect sunt cele două vizualizări text incluse în aspectul listei de elemente. Acum putem crea Adaptorul Simplu de Cursor pentru a cartografia datele către elementele vizibile ale interfeței utilizator:
SimpleCursorAdapter picAdapter = noul SimpleCursorAdapter (acesta, R.layout.pic_item, picCursor, coloane, vizualizări, SimpleCursorAdapter.FLAG_AUTO_REQUERY);
Transmitem aspectul pe care l-am creat pentru fiecare element de listă, cursorul pe care l-am creat pentru a traversa imaginile bazei de date, coloanele și vederile pe care le dorim cartografiate. Acum putem seta acest lucru ca Adaptor pentru Activitatea listei:
setListAdapter (picAdapter);
Acest lucru va face ca numele și ID-urile tuturor imaginilor salvate să fie listate în Vizualizare - în continuare vom implementa selectarea unuia din listă pentru încărcare în câmpul de text.
Rețineți că atunci când am creat aspectul "pic_item", am specificat o onClick atribut pentru fiecare element din listă. Când utilizatorii dau clic pe un element de listă, se va executa metoda specificată - metoda ar trebui să fie inclusă în activitatea care găzduiește aspectul și va primi vizualizarea făcută ca parametru. Adăugați metoda în clasa de activități "PicChooser":
public void picChosen (Vizualizare vedere)
Parametrul Vizualizare este aspectul elementului de listă, care conține două vizualizări de text, unul pentru ID-ul imaginii și unul pentru nume. Vrem să obținem ID-ul imaginii selectate, deci în interiorul metodei, obțineți vizualizarea textului ID din vizualizarea Vizualizată, apoi conținutul textului:
TextView pickedView = (TextView) view.findViewById (R.id.picID); Stringul alesID = (String) pickedView.getText ();
ID-ul ne va permite să preluăm conținutul de imagini din baza de date. Acum vom termina activitatea de selectare a imaginilor și vom returna ID-ul de imagine ales în activitatea principală. Mai întâi închideți conexiunile bazei de date:
picDataHelp.close (); savedPictures.close (); picCursor.close ();
Vom începe această activitate din clasa principală a activității, specificând că ar trebui să returneze un rezultat. Când se încheie această activitate, onActivityResult metoda se va executa, prin urmare, în clasa principală, astfel încât să putem transmite ID-ul imaginii alese de utilizator. Creați o intenție și transmiteți datele:
Intent backIntent = intenție nouă (); backIntent.putExtra ("pickedImg", ID ales);
Setați rezultatul:
setResult (RESULT_OK, backIntent);
Acum putem finaliza această Activitate:
finalizarea();
Înainte de a termina cu clasa "PicChooser", trebuie să facem un pic de menaj. Dacă utilizatorul selectează o imagine din listă, ne-am asigurat că conexiunile bazei de date sunt închise înainte ca Activitatea să se încheie. Cu toate acestea, utilizatorul poate apăsa butonul înapoi pentru a reveni la activitatea principală în loc să aleagă o fotografie. În acest caz, putem închide conexiunea onDestroy, doar adăugați-o la clasă:
@Override public void peDestroy () picCursor.close (); picDataHelp.close (); savedPictures.close (); super.onDestroy ();
Acum avem posibilitatea ca utilizatorii să aleagă din imaginile stocate în baza de date, trebuie doar să încărcăm imaginea aleasă în câmpul text. Înapoi în activitatea principală, adăugați următoarele declarații de import:
import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;
În altfel dacă ați creat pentru clicuri pe butonul de încărcare al metodei ascultătorului de clic, porniți activitatea "PicChooser" pentru un rezultat:
Intent loadIntent = intenție nouă (acest lucru, PicChooser.class); this.startActivityForResult (loadIntent, LOAD_REQUEST);
Rețineți că aceasta este similară cu codul utilizat la lansarea activității de configurare a culorilor, cu o constantă reprezentând un identificator pentru onActivityResult - adăugați variabila constantă în partea de sus a clasei:
finală privată int LOAD_REQUEST = 2;
Acum, când utilizatorul a ales o imagine din lista afișată, ID-ul fotografiei aleasă va fi returnat onActivityResult așa că hai să lucrăm la această metodă. După dacă declarație în care ați manipulat utilizatorii care revin din selectorul de culori Activitate, adăugați o altfel dacă cu un contur similar:
altfel dacă (requestCode == LOAD_REQUEST) if (resultCode == RESULT_OK)
În interiorul acestui bloc, obțineți datele returnate din activitatea "PicChooser":
Codul stringedID = data.getStringExtra ("pickedImg");
Ori de câte ori imaginea afișată în câmpul text este stocată în baza de date, vom păstra o înregistrare a ID-ului imaginii stocate. În partea de sus a clasei, adăugați o variabilă pentru a face acest lucru:
private int currentPic = -1;
Inițializarea acestuia la una negativă ne va permite să verificăm dacă imaginea curentă este din baza de date sau nu. Înapoi în onActivityResult după preluarea datelor din "PicChooser", actualizați această variabilă:
currentPic = Integer.parseInt (pickedID);
Vom folosi aceasta atunci când utilizatorul șterge sau editează o imagine salvată. Obțineți o instanță a bazei de date de la ajutorul:
SQLiteDatabase salvatPicsDB = imgData.getWritableDatabase ();
Solicitați baza de date pentru imaginea cu ID-ul ales:
Cursor alesCursor = savedPicsDB.query ("pics", noul String [] ImageDataHelper.ASCII_COL, ImageDataHelper.ID_COL + "=?", Nou String [] "+ + currentPic, null, null, null);
Ia-ți un moment să te uiți peste asta. Primul parametru este tabelul, al doilea este o matrice de stâlpi care reprezintă coloanele pe care le dorim, în acest caz doar textul care compune imaginea ASCII. Al treilea și al patrulea parametru sunt selecția, în SQL acest lucru ar fi de obicei a Unde interogare, cu ID-ul de imagine ales de utilizator pentru a fi potrivite în coloana ID, astfel încât să recuperăm imaginea respectivă.
Trebuie să existe o singură înregistrare cu ID-ul specificat, astfel că mutați cursorul la prima înregistrare recuperată:
chosenCursor.moveToFirst ();
Obțineți textul pentru imagine:
Stringul savedChars = selectedCursor.getString (0);
Afișați imaginea în câmpul text:
textArea.setText (savedChars);
Închideți cursorul, baza de date și ajutorul:
chosenCursor.close (); savedPicsDB.close (); imgData.close ();
Aceasta este baza noastră de date creată pentru stocarea și încărcarea fotografiilor. Verificați descărcarea codului sursă pentru orice nu sunteți sigur. În momentul în care executați aplicația, nu veți vedea imaginile salvate. Acest lucru se datorează faptului că nu am implementat încă imagini de salvare. Vom face asta data viitoare, în ultima parte a seriei tutorial. Ne vom ocupa, de asemenea, de ștergerea imaginilor, crearea de imagini noi și editarea fotografiilor existente. Apoi editorul nostru de artă ASCII va fi pe deplin funcțional.