日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据存储之SharedPreferences

發(fā)布時間:2025/3/21 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据存储之SharedPreferences 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在Android系統(tǒng)中提供了多張存儲技術(shù),這些存儲技術(shù)可以講數(shù)據(jù)保存在各種存儲介質(zhì)上。例如SharedPreferences可以將數(shù)據(jù)保存在應(yīng)用軟件的私有存儲區(qū),這些存儲區(qū)中的數(shù)據(jù)只能被寫入這些數(shù)據(jù)的軟件讀取。除此之外,Android系統(tǒng)還支持文件存儲、SQLite數(shù)據(jù)庫、OBB文件、云存儲等


SharedPreferences的基本用法

SharedPreferences處理的就是一個key-value對。

它是一個輕量級的存儲類,特別適合用于保存軟件配置參數(shù)。使用SharedPreferences保存數(shù) 據(jù),其背后是用xml文件存放數(shù)據(jù),使用簡易的鍵值對存儲。

//文件命名為demo,私有模式 SharedPreferences sharedPreferences = getSharedPreferences("demo", Context.MODE_PRIVATE); Editor editor = sharedPreferences.edit();//獲取編輯器 editor.putString("name", "hello"); editor.putInt("age", 6); editor.commit();//提交修改

這樣,我們就把信息存儲到了/data/data/<packagename>/shared_prefs/demo.xml文件里面,現(xiàn)在你打開這個文件,就可以看到內(nèi)容已經(jīng)被存儲。如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="name">hello</string> <int name="age" value="6" /> </map>

getSharedPreferences(name,mode) 方法的第一個參數(shù)用于指定該文件的名稱,最好定義為一個靜態(tài)字符串,另外,名稱如上面所示,不用帶后綴名,后綴名會由系統(tǒng)自動加上。方法的第二個參數(shù)指定 文件的操作模式,共有四種操作模式,這四種模式想必大家都有一定的了解。這里簡單說一下:

TypeCommens
MODE_PRIVATE默認模式,在創(chuàng)建的文件只能該應(yīng)用能夠使用(或所有的應(yīng)用程序共享同一個用戶標(biāo)識號)。
MODE_APPEND如果文件已經(jīng)存在,在文件內(nèi)容后面添加。
MODE_WORLD_READABLE允許其他應(yīng)用讀該應(yīng)用創(chuàng)建的文件。
MODE_WORLD_WRITEABLE允許其他應(yīng)用寫該應(yīng)用創(chuàng)建的文件。

所以,如果你希望SharedPreferences背后使用的xml文件能被其他應(yīng)用讀和寫,可以指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE權(quán)限。

另外Activity還提供了另一個getPreferences(mode)方法操作SharedPreferences,這個方法默認使用當(dāng)前類不帶包名的類名作為文件的名稱。

如果我們的模式設(shè)置為Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE權(quán)限,我們其他的應(yīng)用是可以訪問的,下面是其他應(yīng)用訪問的代碼(假如上面代碼的包名為cn.test.demo):

try{Context context = createPackageContext("cn.test.demo", Context.CONTEXT_IGNORE_SECURITY); } catch (NameNotFoundException e){e.printStackTrace(); }

CreatePackageContext這個方法有兩個參數(shù):
1.packageName 包名,要得到Context的包名
2.flags 標(biāo)志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY兩個選項。

CONTEXT_INCLUDE_CODE的意思是包括代碼,也就是說可以執(zhí)行這個包里面的代碼。
CONTEXT_IGNORE_SECURITY的意思 是忽略安全警告,如果不加這個標(biāo)志的話,有些功能是用不了的,會出現(xiàn)安全警告。

CreatePackageContext方法在找不到包名的時候會報NameNotFoundException異常,所以我們要捕獲它。


數(shù)據(jù)的存儲位置和格式

文件存放在/data/data/<packagename> /shared_prefs目錄下

存取復(fù)雜類型的數(shù)據(jù)

不建議使用,但是確實可以存儲復(fù)雜類型的數(shù)據(jù)。

如果想用SharedPreferences存取更加復(fù)雜的數(shù)據(jù)類型(對象圖像等),就需要對這些數(shù)據(jù)進行編碼,通常會將復(fù)雜類型的數(shù)據(jù)轉(zhuǎn)換成Base64格式的編碼,然后將轉(zhuǎn)換后的數(shù)據(jù)以字符串的形式保存在xml文件中。

效果圖

說明

本例將一個Product對象和一個圖像保存在xml文件中,并在程序重新運行后從xml文件裝載Product和圖像。

Code

Product.java

import java.io.Serializable;/*** MyApp** @author Mr.Yang on 2016-02-21 17:08.* @version 1.0* @desc 必須可序列化,需要實現(xiàn)Serializable*/ public class Product implements Serializable {public String name;public int price; }

我們使用了存放在res/drawable中的圖片,下面的代碼將該圖像保存在base64.xml文件中。

將該圖像保存在base64.xml文件中。

try {SharedPreferences sharedPreferences = getSharedPreferences("base64", Activity.MODE_PRIVATE);SharedPreferences.Editor editor = sharedPreferences.edit();// 讀取和壓縮R.drawable.item10,并將其壓縮結(jié)果保存在ByteArrayOutputStream中ByteArrayOutputStream baos = new ByteArrayOutputStream();BitmapFactory.decodeResource(getResources(), R.drawable.item10).compress(Bitmap.CompressFormat.JPEG, 50, baos);// 對壓縮后的字節(jié)進行Base6編碼String imageBase64 = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));// 保存轉(zhuǎn)換后的Base64格式字符串editor.putString("image", imageBase64);editor.commit();// 關(guān)閉輸出流baos.close();Toast.makeText(this, "onClick_Save_Image 成功", Toast.LENGTH_LONG).show();} catch (Exception e) {}

讀取并顯示在ImageView上

try {SharedPreferences sharedPreferences = getSharedPreferences("base64", Activity.MODE_PRIVATE);// 讀取Base64格式的圖片數(shù)據(jù)String imageBase64 = sharedPreferences.getString("image", "");// 對Base64格式的字符串進行解碼,還原成字節(jié)數(shù)組byte[] imageBytes = Base64.decode(imageBase64.getBytes(), Base64.DEFAULT);ByteArrayInputStream bais = new ByteArrayInputStream(imageBytes);// 在控件上顯示圖像ImageView imageView = (ImageView) findViewById(R.id.image);imageView.setImageDrawable(Drawable.createFromStream(bais, "image"));// 關(guān)閉輸入流bais.close();Toast.makeText(this, "onClick_Read_Image 成功", Toast.LENGTH_LONG).show();} catch (Exception e) {}

將Product保存到base64.xml中

try {Product product = new Product();product.name = "如來神掌";product.price = 1500;ByteArrayOutputStream baos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baos);// 將Product對象保存到ObjectOutputStream中oos.writeObject(product);SharedPreferences sharedPreferences = getSharedPreferences("base64", Activity.MODE_PRIVATE);SharedPreferences.Editor editor = sharedPreferences.edit();// 將Product對象轉(zhuǎn)換成byte數(shù)組,并將其進行Base64編碼String productBase64 = new String(Base64.encode(baos.toByteArray(), Base64.DEFAULT));// 將編碼后的字符串保存到base64.xml中editor.putString("product", productBase64);editor.commit();// 輸出流關(guān)閉oos.close();Toast.makeText(this, "onClick_Save_Serializable_Object 成功", Toast.LENGTH_LONG).show();} catch (Exception e) {}

從base64.xml中讀取Product對象

try {SharedPreferences sharedPreferences = getSharedPreferences("base64", Activity.MODE_PRIVATE);// 讀取Product對象的Base64格式的字符串String base64Product = sharedPreferences.getString("product", "");ByteArrayOutputStream baos = new ByteArrayOutputStream();//將base64格式字符串還原成byte數(shù)組byte[] productBytes = Base64.decode(base64Product.getBytes(), Base64.DEFAULT);ByteArrayInputStream bais = new ByteArrayInputStream(productBytes);ObjectInputStream ois = new ObjectInputStream(bais);// 將byte數(shù)組轉(zhuǎn)換成Product對象Product product = (Product) ois.readObject();Toast.makeText(this,"name:" + product.name + "\nprice:" + product.price,Toast.LENGTH_LONG).show();// 關(guān)閉輸入流ois.close();} catch (Exception e) {}

設(shè)置數(shù)據(jù)文件的訪問權(quán)限

/*** MODE_WORLD_READABLE MODE_WORLD_READABLE* "This constant was deprecated in API level 17.* Creating world-readable files is very dangerous,* and likely to cause security holes in applications.* It is strongly discouraged; instead,* applications should use more formal mechanism for interactions* such as ContentProvider, BroadcastReceiver, and Service.* There are no guarantees that this access mode will remain on a file,* such as when it goes through a backup and restore.* File creation mode: allow all other applications to have read access to the created file."*/private void createDiffPermissionSpFile() {int[] modes = new int[]{Activity.MODE_PRIVATE, Activity.MODE_APPEND,Activity.MODE_WORLD_READABLE,Activity.MODE_WORLD_READABLE};for (int i = 0; i < modes.length; i++) {SharedPreferences sharedPreferences = getSharedPreferences("data" + String.valueOf(i + 1), modes[i]);SharedPreferences.Editor editor = sharedPreferences.edit();editor.putString("name", "不同的訪問權(quán)限");editor.commit();}}

觀察生成的文件的權(quán)限,同linux文件系統(tǒng)

可以保存設(shè)置的Activity:PreferenceActivity

概述

Android SDK提供了更加方便的方法來實現(xiàn)配置界面,并且可以透明的保存配置信息,這就是PreferenceActivity.

PreferenceActivity是Activity的子類,該類封裝了SharedPreference,因此PreferenceActivity的所有子類都會擁有保存key-value的能力。

通過PreferenceActivity生成的XML文件在data/data/<工程名>/shared_prefs/下,名字為“<工程名>_Preference.xml。

在PreferenceActivity中,所有的修改都會自動更新該XML文件,不需要我們手動去設(shè)置大量的監(jiān)聽。

PreferenceActivity提供了一些常用的控件,可以滿足大多數(shù)配置界面的要求, PreferenceActivity既可以從xml文件中創(chuàng)建,也可以通過代碼的方式創(chuàng)建。

比較常用的控件有3個:

  • CheckBoxPreference:對應(yīng)<CheckBoxPreference>標(biāo)簽,相當(dāng)于CheckBox
  • EditTextPreference:對應(yīng)<EditTextPreference>標(biāo)簽。單擊該控件會彈出一個帶有EditText的對話框
  • ListPreference:對應(yīng)<ListPreference>標(biāo)簽,單擊該控件會彈出一個帶ListView的對話框。

效果圖

PreferenceActivity在API11之后就廢棄了,建議使用PreferenceFragment。

res目錄下創(chuàng)建一個xml子目錄,建立preference_setting.xml

<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" ><PreferenceCategory android:title="我的位置源" ><CheckBoxPreference android:key="wireless_network"android:summary="使用無線網(wǎng)絡(luò)查看應(yīng)用程序(例如Google地圖)中的位置"android:title="使用無線網(wǎng)絡(luò)" /><CheckBoxPreference android:key="gps_satellite_setting"android:summary="定位時,精確到街道級別(取消選擇可節(jié)約電量)"android:title="啟用GPS衛(wèi)星設(shè)置" /></PreferenceCategory><PreferenceCategory android:title="個人信息設(shè)置" ><CheckBoxPreference android:key="yesno_save_individual_info"android:title="是否保存?zhèn)€人信息" /><EditTextPreference android:key="individual_name"android:summary="請輸入真實姓名"android:title="姓名" /><PreferenceScreen android:key="other_individual_msg"android:summary="是否工作、手機"android:title="其他個人信息" ><CheckBoxPreference android:key="is_an_employee"android:title="是否工作" /><EditTextPreference android:key="mobile"android:summary="請輸入真實的手機號"android:title="手機" /></PreferenceScreen></PreferenceCategory></PreferenceScreen>

PreferenceActivityDemo

package com.turing.base.activity.dataStore.sharedPreference;import android.content.SharedPreferences; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.PreferenceScreen;import com.turing.base.R;/*** 3.0版本以后就需要使用PreferenceFragment,這里用過時的也沒關(guān)系*/ public class PreferenceActivityDemo extends PreferenceActivity implements Preference.OnPreferenceChangeListener {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 改變保存數(shù)據(jù)的xml使用的名稱,默認是<package_name>_preferences.xmlgetPreferenceManager().setSharedPreferencesName("setting");// 從xml文件中加載布局addPreferencesFromResource(R.xml.preference_setting);// 獲取"姓名"列表項對應(yīng)的Preference對象Preference individualNamePreference = findPreference("individual_name");// 獲得指向setting.xml文件的SharedPreferences對象SharedPreferences sharedPreferences = individualNamePreference.getSharedPreferences();// 設(shè)置列表項的SummaryindividualNamePreference.setSummary(sharedPreferences.getString("individual_name", ""));//設(shè)置"姓名"列表項是否可用if (sharedPreferences.getBoolean("yesno_save_individual_info", false))individualNamePreference.setEnabled(true);elseindividualNamePreference.setEnabled(false);// 設(shè)置包含onPreferenceChange事件的對象實例individualNamePreference.setOnPreferenceChangeListener(this);//mobile// 獲取"mobile"列表項對應(yīng)的Preference對象Preference mobilePreference = findPreference("mobile");// 獲得指向setting.xml文件的SharedPreferences對象SharedPreferences mobileSP = mobilePreference.getSharedPreferences();// 設(shè)置列表項的SummarymobilePreference.setSummary(mobileSP.getString("mobile", ""));// 設(shè)置包含onPreferenceChange事件的對象實例mobilePreference.setOnPreferenceChangeListener(this);}@Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {// 設(shè)置"姓名"列表項中Summary的值preference.setSummary(String.valueOf(newValue));// 必須返回為true,否則無法保存設(shè)置的值return true;}/*** 狀態(tài)改變后的自動文件存儲 需要繼承PreferenceActivity的類和實現(xiàn)OnPreferenceChangeListener接口,* 重寫onPreferenceTreeClick方法進行業(yè)務(wù)邏輯處理* @param preferenceScreen* @param preference* @return*/@Overridepublic boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,Preference preference) {// 判斷選中的是否為"是否保存?zhèn)€人信息"列表項的復(fù)選框if ("yesno_save_individual_info".equals(preference.getKey())) {// 設(shè)置姓名為可選或者不可選findPreference("individual_name").setEnabled(!findPreference("individual_name").isEnabled());}return super.onPreferenceTreeClick(preferenceScreen, preference);} }

總結(jié)

以上是生活随笔為你收集整理的数据存储之SharedPreferences的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。