How to store data locally in an Android app

文章推薦指數: 80 %
投票人數:10人

Internal storage LinksonAndroidAuthoritymayearnusacommission. Learnmore. HowtostoredatalocallyinanAndroidappWedigintothedifferentoptionsavailabletostoredatalocallyonanandroiddevice,completewithsamplesourcecode.AndroidDevelopmentByRyanHaines•May24,2021Almosteveryappweuseordevelophastostoredataforonepurposeoranother.It’snotallthesamedata,either—someappsneedaccesstosettings,images,andmuchmore.Thebigquestionishowtomanagethisdatasothatyourdevicecangrabonlywhatitneeds.Luckilyfordevelopers,Androidisfullofwaystostoredata,andwe’reheretorunyouthroughhowtheywork. Seealso: Makinganappwithnoprogrammingexperience:Whatareyouroptions?Forthisarticle,we’lldiscussthedifferentdatastoragetechniquesavailabletoAndroiddevelopers,alongwithsamplecodetogetyoustartedortorefreshyourmemory. Waystostoredata SharedPreferences Internalstorage Externalstorage SQLitedatabases Savingcachefiles UsingSharedPreferencesSharedPreferencesisthewaytogoifyou’resavingprimitivedataaskey-valuepairs.Itrequiresakey,whichisaString,andthecorrespondingvalueforthesaidkey.Thevaluecanbeanyofthefollowing:aboolean,float,int,long,oranotherstring.YourAndroiddevicestoreseachapp’sSharedPreferencesinsideofanXMLfileinaprivatedirectory.AppscanalsohavemorethanoneSharedPreferencesfile,andthey’reideallyusedtostoreapppreferences. Seealso: AndroidStudio4.1–NewfeaturesfordevsBeforeyoucanstoredatawithsharedpreferences,youmustfirstgetaSharedPreferencesobject.TherearetwoContextmethodsthatyoucanusetoretrieveaSharedPreferencesobject. CodeCopyTextSharedPreferencessharedPreferences=getPreferences(MODE_PRIVATE); Forwhenyourappwillhaveasinglepreferencesfile,and CodeCopyTextSharedPreferencessharedPreferences=getSharedPreferences(fileNameString,MODE_PRIVATE); forwhenyourappcouldhavemultiplepreferencesfiles,orifyouprefertonameyourSharedPreferencesinstance.OngettingtheSharedPreferencesobject,youthenaccessitsEditorusingtheedit()method.Toactuallyaddavalue,usetheEditor’sputXXX()method,whereXXXisoneofBoolean,String,Float,Long,Int,orStringSet.Youcanalsoremoveakey-valuepreferencepairwithremove().Finally,makesuretocalltheEditor’scommit()methodafterputtingorremovingvalues.Ifyoudon’tcallcommit,yourchangeswillnotbepersisted. CodeCopyTextSharedPreferences.Editoreditor=sharedPreferences.edit(); editor.putString(keyString,valueString); editor.commit(); Foroursampleapp,weallowtheusertospecifyaSharedPreferencesfilename.Iftheuserspecifiesaname,werequestfortheSharedPreferenceswiththatname;ifnot,werequestthedefaultSharedPreferenceobject. CodeCopyTextStringfileNameString=sharedPreferencesBinding.fileNameEditView.getText().toString(); SharedPreferencessharedPreferences; if(fileNameString.isEmpty()){ sharedPreferences=getPreferences(MODE_PRIVATE); } else{ sharedPreferences=getSharedPreferences(fileNameString,MODE_PRIVATE); } Unfortunately,thereisnowaytogetasinglelistofallSharedPreferencesfilesstoredbyyourapp.Instead,youwillneedastaticlistoraccesstotheSharedPreferencesnameifyou’restoringmorethanonefile.YoucouldalsosaveyourSharedPreferencesnamesinthedefaultfile.Ifyouneedtostoreuserpreferences,youmaywanttousethePreferenceActivityorPreferenceFragmentcommand.JustrememberthattheybothuseSharedPreferences,too. UsinginternalstorageThereareplentyoftimeswhereyoumayneedtopersistdata,butyoufindSharedPreferencestoolimiting.Forexample,youmayneedtopersistobjectsorimagesinJava.Youmightalsoneedtopersistyourdatalogicallywiththefilesystemhierarchy.Thisiswhereinternalstoragecomesin.Itisspecificallyforwhenyouneedtostoredataonthefilesystem,butyoudon’twantotherappsoruserstohaveaccess.Thisdatastorageissoprivate,infact,thatit’sdeletedfromthedeviceassoonasyouuninstallyourapp.Usinginternalstorageissimilartosavingwithanyotherfilesystem.YoucangetreferencestoFileobjects,andyoucanstoredataofvirtuallyanytypeusingaFileOutputStream.Whatsetsitapartisthefactthatitscontentsareonlyaccessiblebyyourapp.Togetaccesstoyourinternalfiledirectory,usetheContextgetFilesDir()method.Tocreate(oraccess)adirectorywithinthisinternalfiledirectory,usethegetDir(directoryName,Context.MODE_XXX)method.ThegetDir()methodreturnsareferencetoaFileobjectrepresentingthespecifieddirectory,creatingitfirstifitdoesn’texist. CodeCopyTextFiledirectory; if(filename.isEmpty()){ directory=getFilesDir(); } else{ directory=getDir(filename,MODE_PRIVATE); } File[]files=directory.listFiles(); Inthesampleabove,iftheuser-specifiedfilenameisempty,wegetthebaseinternalstoragedirectory.Iftheuserspecifiesaname,wegetthenameddirectory,creatingfirstifneeded.Toreadfiles,useyourpreferredfilereadingmethod.Forourexample,wereadthecompletefileusingaScannerobject.Toreadafilethat’sdirectlywithinyourinternalstoragedirectory(notinanysubdirectory),youcanusetheopenFileInput(fileName)method. CodeCopyTextFileInputStreamfis=openFileInput(filename); Scannerscanner=newScanner(fis); scanner.useDelimiter("\\Z"); Stringcontent=scanner.next(); scanner.close(); Similarly,toaccessafileforwritingdirectlywithintheInternalStoragedirectory,usetheopenFileOutput(fileName)method.Tosavefiles,weusetheFileOutputStreamwrite. CodeCopyTextFileOutputStreamfos=openFileOutput(filename,Context.MODE_PRIVATE); fos.write(internalStorageBinding.saveFileEditText.getText().toString().getBytes()); fos.close(); Asyoucanseeintheimageabove,thefilepathisinafoldernotaccessiblebythefilemanagerorotherapps.Theonlyexceptiontothiswillbeifyouhavearooteddevice. ExternalStorageWesternDigitalGooglehasmadeafewkeychangestoexternalstorage,beginningwithAndroid10andcontinuinginAndroid11.Togiveusersbettercontrolovertheirfilesandcutdownonclutter,appsnowhavescopedaccesstoexternalstoragebydefault.Thismeansthattheycantapintothespecificdirectoryonexternalstorageandthemediathattheappcreates.Formoreinformationaboutrequestingscopeddirectoryaccess,checkoutthisAndroiddevelopertutorial.Ifyourapptriestoaccessafilethatitdidnotcreate,youwillhavetopermitittodosoeverysingletime.Datayoustoreoutsideofselectfolderswillalsodisappearifyoudeleteyourapp.Appsareexpectedtostorefilesinoneoftwoapp-specificlocationsdesignedfortheapp’sspecificpersistentfilesandcachedfiles,respectively.Toaccesstheselocations,theappmustverifythestorageisavailable(whichisnotguaranteed,asitisforinternalstorage).Thevolume’sstatecanbequeriedusing: CodeCopyTextEnvironment.getExternalStorageStage(). IfMEDIA_MOUNTEDisreturned,thatmeansyoucanreadandwritefilestoexternalstorage.Youwillfindanumberofpredefineddirectoriesthatshouldaidwithlogicalstorageandpreventclutter.TheseincludethelikesofDIRECTORY_DOCUMENTSandDIRECTORY_MOVIES.Youcanreadafullexplanationofhowtousescopedstoragehere. SQLitedatabaseFinally,AndroidprovidessupportforappstouseSQLitedatabasesfordatastorage.Thedatabasesyoucreateremainspecifictoyourappandcanonlybeaccessedinsideyourapp.Ofcourse,youshouldhaveatleastsomeknowledgeofSQLbeforeyouattempttostoredatawithanSQLitedatabase. Seealso: AguidetoAndroidappdevelopmentforcompletebeginnersinfiveeasystepsWe’lldiscusseachoftheseinturn,andweusedatabindingtechniquesforoursamplecode.AndroidprovidescompletesupportforSQLitedatabases.TherecommendedwayofcreatingSQLitedatabasesistosubclasstheSQLiteOpenHelperclassandoverridetheonCreate()method.Forthissample,wecreateasingletable. CodeCopyTextpublicclassSampleSQLiteDBHelperextendsSQLiteOpenHelper{ privatestaticfinalintDATABASE_VERSION=2; publicstaticfinalStringDATABASE_NAME="sample_database"; publicstaticfinalStringPERSON_TABLE_NAME="person"; publicstaticfinalStringPERSON_COLUMN_ID="_id"; publicstaticfinalStringPERSON_COLUMN_NAME="name"; publicstaticfinalStringPERSON_COLUMN_AGE="age"; publicstaticfinalStringPERSON_COLUMN_GENDER="gender"; publicSampleSQLiteDBHelper(Contextcontext){ super(context,DATABASE_NAME,null,DATABASE_VERSION); } @Override publicvoidonCreate(SQLiteDatabasesqLiteDatabase){ sqLiteDatabase.execSQL("CREATETABLE"+PERSON_TABLE_NAME+"("+ PERSON_COLUMN_ID+"INTEGERPRIMARYKEYAUTOINCREMENT,"+ PERSON_COLUMN_NAME+"TEXT,"+ PERSON_COLUMN_AGE+"INTUNSIGNED,"+ PERSON_COLUMN_GENDER+"TEXT"+")"); } @Override publicvoidonUpgrade(SQLiteDatabasesqLiteDatabase,inti,inti1){ sqLiteDatabase.execSQL("DROPTABLEIFEXISTS"+PERSON_TABLE_NAME); onCreate(sqLiteDatabase); } } Toadddata: CodeCopyTextprivatevoidsaveToDB(){ SQLiteDatabasedatabase=newSampleSQLiteDBHelper(this).getWritableDatabase(); ContentValuesvalues=newContentValues(); values.put(SampleSQLiteDBHelper.PERSON_COLUMN_NAME,activityBinding.nameEditText.getText().toString()); values.put(SampleSQLiteDBHelper.PERSON_COLUMN_AGE,activityBinding.ageEditText.getText().toString()); values.put(SampleSQLiteDBHelper.PERSON_COLUMN_GENDER,activityBinding.genderEditText.getText().toString()); longnewRowId=database.insert(SampleSQLiteDBHelper.PERSON_TABLE_NAME,null,values); Toast.makeText(this,"ThenewRowIdis"+newRowId,Toast.LENGTH_LONG).show(); } Toreaddata: CodeCopyTextprivatevoidreadFromDB(){ Stringname=activityBinding.nameEditText.getText().toString(); Stringgender=activityBinding.genderEditText.getText().toString(); Stringage=activityBinding.ageEditText.getText().toString(); if(age.isEmpty()) age="0"; SQLiteDatabasedatabase=newSampleSQLiteDBHelper(this).getReadableDatabase(); String[]projection={ SampleSQLiteDBHelper.PERSON_COLUMN_ID, SampleSQLiteDBHelper.PERSON_COLUMN_NAME, SampleSQLiteDBHelper.PERSON_COLUMN_AGE, SampleSQLiteDBHelper.PERSON_COLUMN_GENDER }; Stringselection= SampleSQLiteDBHelper.PERSON_COLUMN_NAME+"like?and"+ SampleSQLiteDBHelper.PERSON_COLUMN_AGE+">?and"+ SampleSQLiteDBHelper.PERSON_COLUMN_GENDER+"like?"; String[]selectionArgs={"%"+name+"%",age,"%"+gender+"%"}; Cursorcursor=database.query( SampleSQLiteDBHelper.PERSON_TABLE_NAME,//Thetabletoquery projection,//Thecolumnstoreturn selection,//ThecolumnsfortheWHEREclause selectionArgs,//ThevaluesfortheWHEREclause null,//don'tgrouptherows null,//don'tfilterbyrowgroups null//don'tsort ); Log.d("TAG","Thetotalcursorcountis"+cursor.getCount()); activityBinding.recycleView.setAdapter(newMyRecyclerViewCursorAdapter(this,cursor)); } SQLitestorageoffersthepowerandspeedofafull-featuredrelationaldatabasetoyourapp.Ifyouintendtostoredatathatyoumaylaterquery,youshouldconsiderusingtheSQLitestorageoption. SavingCacheFilesAndroidalsoprovidesameanstocachesomedataratherthanstoreitpermanently.Youcancachedataineitherinternalstorageorexternalstorage.CachefilesmaybedeletedbytheAndroidsystemwhenthedeviceislowonspace. Seealso: HowtoclearappcacheontheSamsungGalaxyS10Togettheinternalstoragecachedirectory,usethegetCacheDir()method.ThisreturnsaFileobjectthatrepresentsyourapp’sinternalstoragedirectory.YoucanaccesstheexternalcachedirectorywiththesimilarlynamedgetExternalCacheDir().AlthoughtheAndroiddevicecandeleteyourcachefilesifneeded,youshouldnotrelyonthisbehavior.Instead,youshouldmaintainthesizeofyourcachefilesyourselfandalwaystrytokeepyourcachewithinareasonablelimit,liketherecommended1MB. So,whichmethodshouldyouuse?Thereareadvantagesanddisadvantagestousingeachofthedifferentstoragemethodsavailable.SharedPreferencesistheeasiesttouse,especiallyifyouwanttostorediscreteprimitivedatatypes.However,internalandexternalstorageisbestforstoringfilessuchasmusic,videos,anddocuments,whileSQLitewinsifyouneedtoperformfastsearchesandqueriesonyourdata.Ultimately,thestoragemethodyouchooseshoulddependonyourdatatypes,thelengthoftimeyouneedthedata,andhowprivateyouwantthedatatobe.YoucanstillgrabthesourcecodefortheappaboveonGitHubifyou’rehopingtopracticeforyourself.Feelfreetouseitasyouseefit,anddon’thesitatetoreachoutinthecommentsbelow. Readnext: PythonvsJava:Whichlanguageshouldyoulearnandwhatarethedifferences? AndroidDevelopmentHowToAppdevelopmentComments



請為這篇文章評分?