Kotlin數(shù)據(jù)存儲(chǔ)方式全面總結(jié)講解
1、文件存儲(chǔ)
文件存儲(chǔ)是Android中最基本的數(shù)據(jù)存儲(chǔ)方式,它不對(duì)存儲(chǔ)的內(nèi)容進(jìn)行任何格式化處理,有數(shù)據(jù)都是原封不動(dòng)地保存在文件當(dāng)中的,因此它比較適合存儲(chǔ)一些簡(jiǎn)單的文本數(shù)據(jù)或者二進(jìn)制數(shù)據(jù)。
(1)將數(shù)據(jù)存儲(chǔ)在文件中
Context類(lèi)中提供了一個(gè)openFileOutput()方法,用于將數(shù)據(jù)存儲(chǔ)到指定的文件中。
第一個(gè)參數(shù):文件名(系統(tǒng)會(huì)自動(dòng)創(chuàng)建這個(gè)文件)。
第二個(gè)參數(shù):文件的操作模式。
文件的操作模式有以下幾種:
- Context.MODE_PRIVATE:私有覆蓋模式。只能被當(dāng)前應(yīng)用訪問(wèn),并且如果寫(xiě)入,則覆蓋。
- Context.MODE_APPEND:私有追加模式。只能被當(dāng)前應(yīng)用訪問(wèn),并且如果寫(xiě)入,則追加。
- Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE已在Android4.2版本中被廢除。
具體實(shí)現(xiàn):
private fun save(inputText: String) { try { val output=openFileOutput("data", Context.MODE_PRIVATE) val writer=BufferedWriter(OutputStreamWriter(output)) //這里使用了kotlin的內(nèi)置函數(shù)use,它會(huì)保證在Lambda //表達(dá)式中的代碼全部執(zhí)行完之后自動(dòng)將外層的流關(guān)閉,這 //樣就不再需要我們寫(xiě)一個(gè)finally語(yǔ)句,手動(dòng)關(guān)閉流。 writer.use { it.write(inputText) } Toast.makeText(this,inputText,Toast.LENGTH_SHORT).show() }catch (e:IOException){ e.printStackTrace() } }
如何證實(shí)數(shù)據(jù)是否已經(jīng)保存成功了呢?
使用快捷鍵Ctrl+Shift+A(Mac系統(tǒng)是command+shift+A)打開(kāi)搜索功能,在搜索框輸入“Device File Explorer”即可找到這個(gè)工具,我們?cè)谶@工具里找到/data/data/com.example.filepersistencetest/files/目錄,里面有一個(gè)生成的data文件,雙擊打開(kāi),查看里面的內(nèi)容。
(2)從文件中讀取數(shù)據(jù)
Context類(lèi)提供的openFileinput()方法,用于從文件中讀取數(shù)據(jù)。
參數(shù):文件名。
具體實(shí)現(xiàn):
private fun load():String{ val content=StringBuilder() try { val input=openFileInput("data") val reader=BufferedReader(InputStreamReader(input)) //kotlin提供的內(nèi)置擴(kuò)展函數(shù)forEachLine,它會(huì)將讀到的內(nèi)容都回調(diào)到Lambda表達(dá)式中。 reader.use { reader.forEachLine { content.append(it) } } }catch(e:IOException){ e.printStackTrace() } return content.toString() }
(3)實(shí)戰(zhàn)演練:重新啟動(dòng)程序時(shí)EditText中能保留我們上次輸入的內(nèi)容。、
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val inputText=load() if(inputText.isNotEmpty()){ val editText:EditText=findViewById(R.id.editText) editText.setText(inputText) editText.setSelection(inputText.length) } } override fun onDestroy() { super.onDestroy() val editText:EditText=findViewById(R.id.editText) val inputText=editText.text.toString() save(inputText) } private fun save(inputText: String) { try { val output=openFileOutput("data", Context.MODE_PRIVATE) val writer=BufferedWriter(OutputStreamWriter(output)) writer.use { it.write(inputText) } Toast.makeText(this,inputText,Toast.LENGTH_SHORT).show() }catch (e:IOException){ e.printStackTrace() } } private fun load():String{ val content=StringBuilder() try { val input=openFileInput("data") val reader=BufferedReader(InputStreamReader(input)) reader.use { reader.forEachLine { content.append(it) } } }catch(e:IOException){ e.printStackTrace() } return content.toString() } }
2、SharedPreferences存儲(chǔ)
不同于文件存儲(chǔ),SharedPreferences是使用鍵值對(duì)的方式來(lái)存儲(chǔ)數(shù)據(jù)的。
Context類(lèi)中的getSharedPreferences()方法,獲取SharedPreferences對(duì)象。
第一個(gè)參數(shù):指定SharedPreferences文件的名稱(chēng)。(如果指定文件的名稱(chēng)不存在就會(huì)創(chuàng)建一個(gè),SharedPreferences文件都是存放在/data/data/<package name>/shared_prefs目錄)。
第二個(gè)參數(shù):指定操作模式。只有MODE_PRIVATE可選,MODE_PRIVATE:只有當(dāng)前的應(yīng)用程序才可以對(duì)這個(gè)SharedPreferences文件進(jìn)行讀寫(xiě)。
將數(shù)據(jù)存儲(chǔ)到SharedPreferences中
具體實(shí)現(xiàn):
val editor=getSharedPreferences("data", Context.MODE_PRIVATE).edit() editor.putString("name","Tom") editor.putInt("age",28) editor.putBoolean("married",false) editor.apply()//提交
如何證實(shí)數(shù)據(jù)是否已經(jīng)保存成功了呢?
使用快捷鍵Ctrl+Shift+A(Mac系統(tǒng)是command+shift+A)打開(kāi)搜索功能,在搜索框輸入“Device File Explorer”即可找到這個(gè)工具,我們?cè)谶@工具里找到/data/data/com.example.sharedpreferencestest/shared_prefs/目錄,里面有一個(gè)生成的data.xml文件,雙擊打開(kāi),查看里面的內(nèi)容。
從sharedpreferences中讀取數(shù)據(jù)
具體實(shí)現(xiàn)
val prefs=getSharedPreferences("data",Context.MODE_PRIVATE) val name=prefs.getString("name","") val age=prefs.getInt("age",0) val married=prefs.getBoolean("married",false) Log.d("MainActivity","name is $name") Log.d("MainActivity","age is $age") Log.d("MainActivity","married is $married")
3、SQLite數(shù)據(jù)庫(kù)存儲(chǔ)
創(chuàng)建數(shù)據(jù)庫(kù)
SQLiteOpenHelper類(lèi)是一個(gè)抽象類(lèi),有兩個(gè)抽象方法,onCreate()和onUpgrade()。
- onCreate(SQLiteDatabase):在數(shù)據(jù)第一次生成的時(shí)候會(huì)調(diào)用這個(gè)方法,也就是說(shuō),只有創(chuàng)建數(shù)據(jù)庫(kù)的時(shí)候才會(huì)調(diào)用,還可以在這個(gè)方法里生成數(shù)據(jù)庫(kù)表。
- onUpgrade(SQLiteDatabase,int,int):當(dāng)數(shù)據(jù)庫(kù)需要升級(jí)的時(shí)候,Android系統(tǒng)會(huì)自動(dòng)調(diào)用這個(gè)方法,一般在這個(gè)方法里刪除數(shù)據(jù)表,并建立新的數(shù)據(jù)表。
SQLiteOpenHelper類(lèi)的構(gòu)造方法:
第一個(gè)參數(shù):Context
第二個(gè)參數(shù):數(shù)據(jù)庫(kù)名
第三個(gè)參數(shù):運(yùn)行我們?cè)诓樵?xún)數(shù)據(jù)時(shí)放回一個(gè)自定義的Cursor,一般傳入null即可
第四個(gè)參數(shù):表明當(dāng)前數(shù)據(jù)庫(kù)的版本號(hào)
步驟
定義SQLiteOpenHelper的子類(lèi),在該類(lèi)中創(chuàng)建一個(gè)名為BookStore.db的數(shù)據(jù)庫(kù)
class MyDatabaseHelper(val context: Context,name:String,version:Int) :SQLiteOpenHelper(context,name,null,version) { private val createBook = "create table Book(" + " id integer primary key autoincrement," + "author text," + "price real," + "pages integer," + "name text)" private val createCategory = "create table Category(" + "id integer primary key autoincrement," + "category_name text," + "category_code integer)" override fun onCreate(p0: SQLiteDatabase?) { if (p0 != null) { p0.execSQL(createBook) p0.execSQL(createCategory) } Toast.makeText(context,"Create succeeded",Toast.LENGTH_SHORT).show() } override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) { if (p0 != null) { p0.execSQL("drop table if exists Book") p0.execSQL("drop table if exists Category") onCreate(p0) } } }
調(diào)用MyDatabaseHelper類(lèi)完成表的創(chuàng)建
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val dbHelper=MyDatabaseHelper(this,"BookStore.db",1) dbHelper.writableDatabase } }
升級(jí)數(shù)據(jù)庫(kù)
把
val dbHelper=MyDatabaseHelper(this,"BookStore.db",1)
改為
val dbHelper=MyDatabaseHelper(this,"BookStore.db",2)
表示數(shù)據(jù)庫(kù)升級(jí)
添加數(shù)據(jù)
insert():專(zhuān)門(mén)用于添加數(shù)據(jù)。
第一個(gè)參數(shù):表名
第二個(gè)參數(shù):用于在未指定添加數(shù)據(jù)的情況下給某些可為空的列自動(dòng)賦值給NULL,一般用不到這個(gè)功能,傳入null即可。
第三個(gè)參數(shù):ContentValues對(duì)象
步驟
獲取SQLiteDatabase對(duì)象
val dbHelper=MyDatabaseHelper(this,"BookStore.db",1) val db=dbHelper.writableDatabase
使用ContentValues對(duì)要添加的數(shù)據(jù)進(jìn)行組裝
val values1=ContentValues().apply { put("name","The Da Vinci Code") put("author","Dan Brown") put("pages",454) put("price",16.96) }
調(diào)用insert()方法將數(shù)據(jù)添加到表中
db.insert("Book",null,values1)
更新數(shù)據(jù)
updata():對(duì)數(shù)據(jù)進(jìn)行更新。
參數(shù):第一個(gè)參數(shù):表名,指定更新哪張表的數(shù)據(jù)。
第二個(gè)參數(shù):ContentValues對(duì)象,要把更新數(shù)據(jù)在這里組裝進(jìn)去。
第三、四個(gè)參數(shù):用于約束更新某一行或某幾行的數(shù)據(jù),不指定的話默認(rèn)會(huì)更新所有行。
步驟
獲取SQLiteDatabase對(duì)象
val dbHelper=MyDatabaseHelper(this,"BookStore.db",1) val db=dbHelper.writableDatabase
構(gòu)建ContentValues對(duì)象,并且給它指定一組數(shù)據(jù),說(shuō)明把價(jià)格這一系列的數(shù)據(jù)更新成10.99。
val values=ContentValues() values.put("price",10.99)
調(diào)用SQLiteDatabase的updata()執(zhí)行具體的更新操作。
db.update("Book",values,"name=?", arrayOf("The Da Vinci Code"))
刪除數(shù)據(jù)
delete()方法:專(zhuān)門(mén)用于刪除數(shù)據(jù)。
第一個(gè)參數(shù):表名
第二、三個(gè)參數(shù):用于約束刪除某一行或者某幾行的數(shù)據(jù),不指定的話會(huì)默認(rèn)刪除所有行。
val dbHelper=MyDatabaseHelper(this,"BookStore.db",1) val db=dbHelper.writableDatabase db.delete("Book","pages>?", arrayOf("500"))
查詢(xún)數(shù)據(jù)
步驟
獲取SQLiteDatabase對(duì)象
val dbHelper=MyDatabaseHelper(this,"BookStore.db",1) val db=dbHelper.writableDatabase
調(diào)用query()方法后會(huì)返回一個(gè)Cursor對(duì)象,查詢(xún)到的所有數(shù)據(jù)都可以從這個(gè)對(duì)象中取出。
val cursor=db.query("Book",null,null,null,null,null,null) //查詢(xún)完后獲得一個(gè)Cursor對(duì)象,接著我們調(diào)用它的moveToFirst()方法, //將數(shù)據(jù)的指針移動(dòng)到第一行的位置, //然后進(jìn)入一個(gè)循環(huán)當(dāng)中,去遍歷查詢(xún)到的每一行數(shù)據(jù) if(cursor.moveToFirst()){ do{ val name=cursor.getString(cursor.getColumnIndex("name")) val author=cursor.getString(cursor.getColumnIndex("author")) val pages=cursor.getInt(cursor.getColumnIndex("pages")) val price=cursor.getDouble(cursor.getColumnIndex("price")) Log.d("MainActivity","Book name is $name") Log.d("MainActivity","Book author is $author") Log.d("MainActivity","Book pages is $pages") Log.d("MainActivity","Book price is $price") }while (cursor.moveToNext()) } cursor.close()
4、使用SQL操作數(shù)據(jù)庫(kù)
使用SQL來(lái)完成前面學(xué)過(guò)的CRUD操作。
添加數(shù)據(jù):
db.execSQL("insert into Book(name, author, pages, price) values(?,?,?,?)", array0f("The Da Vinci Code","Dan Brown","454","16.96") ) db.execSQL("insert into Book(name, author, pages, price) values(?,?,?,?)", array0f("The Lost Symbol","Dan Brown","510","19.95") )
更新數(shù)據(jù):
db.execSQL("update Book set price=? where name=?",array0f("10.99","The Da Vinci Code"))
刪除數(shù)據(jù):
db.execSQL("delete from Book where pages>?",array0f("500"))
查詢(xún)數(shù)據(jù):
val cursor=db.rawQuery("select*from Book", null)
到此這篇關(guān)于Kotlin數(shù)據(jù)存儲(chǔ)方式全面總結(jié)講解的文章就介紹到這了,更多相關(guān)Kotlin數(shù)據(jù)存儲(chǔ)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Kotlin 封裝萬(wàn)能SharedPreferences存取任何類(lèi)型詳解
- Android Kotlin使用SQLite案例詳解
- Android SharedPreferences數(shù)據(jù)存儲(chǔ)詳解
- Android數(shù)據(jù)存儲(chǔ)方式操作模式解析
- Android 通過(guò)SQLite數(shù)據(jù)庫(kù)實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)管理
- Android四種數(shù)據(jù)存儲(chǔ)的應(yīng)用方式
- Android基礎(chǔ)教程數(shù)據(jù)存儲(chǔ)之文件存儲(chǔ)
- Android SharedPreferences實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)功能
相關(guān)文章
Android實(shí)現(xiàn)recyclerview城市字母索引列表
大家好,本篇文章主要講的是Android實(shí)現(xiàn)recyclerview城市字母索引列表,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-01-01Android保存多張圖片到本地的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Android保存多張圖片到本地的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)各位Android開(kāi)發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06Android?實(shí)現(xiàn)單指滑動(dòng)雙指縮放照片demo及過(guò)程解析
這篇文章主要為大家介紹了Android?實(shí)現(xiàn)單指滑動(dòng)雙指縮放照片demo及過(guò)程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04MVVMLight項(xiàng)目Model?View結(jié)構(gòu)及全局視圖模型注入器
這篇文章主要為大家介紹了MVVMLight項(xiàng)目中Model及View的結(jié)構(gòu)及全局視圖模型注入器的使用說(shuō)明,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-01-01手把手教學(xué)Android用jsoup解析html實(shí)例
本篇文章主要介紹了手把手教學(xué)Android用jsoup解析html實(shí)例,jsoup 是一款Java 的HTML解析器。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Android程序開(kāi)發(fā)仿新版QQ鎖屏下彈窗功能
最近做了一個(gè)項(xiàng)目,其中涉及到這樣一個(gè)功能:新版的qq能在鎖屏下彈窗顯示qq消息,下面小編抽時(shí)間把實(shí)現(xiàn)代碼分享給大家感興趣的朋友參考下吧2016-09-09Android向node.js編寫(xiě)的服務(wù)器發(fā)送數(shù)據(jù)并接收請(qǐng)求
這篇文章主要為大家詳細(xì)介紹了Android向node.js編寫(xiě)的服務(wù)器發(fā)送數(shù)據(jù),并接收請(qǐng)求,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10深入Android Handler,MessageQueue與Looper關(guān)系
這篇文章主要介紹了深入Android Handler,MessageQueue與Looper關(guān)系,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08