1.概述
SharedPreferences是Android提供用來存儲一些簡單配置信息的機制,其以KEY-VALUE對的方式進行存儲,以便咱們能夠方便進行讀取和存儲。主要能夠用來存儲應用程序的歡迎語、常量參數或登陸帳號密碼等。
2.實例
(1)建立項目SharedPreferencesDemo項目
(2)編輯主界面的佈局文件main.xml以下:
html
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="SharedPreferences,是Android提供用來存儲一些簡單的配置信息的一種機制。"
- />
- <EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtAccount" android:text=""></EditText>
- <EditText android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/edtPassword" android:text=""></EditText>
- <Button android:text="清空" android:id="@+id/btnClear" android:layout_width="fill_parent" android:layout_height="wrap_content"> </Button>
- <Button android:text="退出" android:id="@+id/btnExit" android:layout_width="fill_parent" android:layout_height="wrap_content"></Button>
- </LinearLayout>
(3)建立AES加解密工具類AESEncryptor.java
其中主要提供加密encrypt、解密decrypt兩個方法。(AES加解密算法具體你們能夠到網上搜索相關資料)
如下爲該類文件的源碼:
- package ni.demo.sharedpreferences;
- import java.security.SecureRandom;
- import javax.crypto.Cipher;
- import javax.crypto.KeyGenerator;
- import javax.crypto.SecretKey;
- import javax.crypto.spec.SecretKeySpec;
- /**
- * AES加密器
- * @author Eric_Ni
- *
- */
- public class AESEncryptor {
- /**
- * AES加密
- */
- public static String encrypt(String seed, String cleartext) throws Exception {
- byte[] rawKey = getRawKey(seed.getBytes());
- byte[] result = encrypt(rawKey, cleartext.getBytes());
- return toHex(result);
- }
-
- /**
- * AES解密
- */
- public static String decrypt(String seed, String encrypted) throws Exception {
- byte[] rawKey = getRawKey(seed.getBytes());
- byte[] enc = toByte(encrypted);
- byte[] result = decrypt(rawKey, enc);
- return new String(result);
- }
-
- private static byte[] getRawKey(byte[] seed) throws Exception {
- KeyGenerator kgen = KeyGenerator.getInstance("AES");
- SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
- sr.setSeed(seed);
- kgen.init(128, sr); // 192 and 256 bits may not be available
- SecretKey skey = kgen.generateKey();
- byte[] raw = skey.getEncoded();
- return raw;
- }
-
-
- private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
- SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
- Cipher cipher = Cipher.getInstance("AES");
- cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
- byte[] encrypted = cipher.doFinal(clear);
- return encrypted;
- }
-
- private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
- SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
- Cipher cipher = Cipher.getInstance("AES");
- cipher.init(Cipher.DECRYPT_MODE, skeySpec);
- byte[] decrypted = cipher.doFinal(encrypted);
- return decrypted;
- }
-
- public static String toHex(String txt) {
- return toHex(txt.getBytes());
- }
- public static String fromHex(String hex) {
- return new String(toByte(hex));
- }
-
- public static byte[] toByte(String hexString) {
- int len = hexString.length()/2;
- byte[] result = new byte[len];
- for (int i = 0; i < len; i++)
- result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
- return result;
- }
-
- public static String toHex(byte[] buf) {
- if (buf == null)
- return "";
- StringBuffer result = new StringBuffer(2*buf.length);
- for (int i = 0; i < buf.length; i++) {
- appendHex(result, buf[i]);
- }
- return result.toString();
- }
- private final static String HEX = "0123456789ABCDEF";
- private static void appendHex(StringBuffer sb, byte b) {
- sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
- }
- }
(4)編輯SharedPreferencesDemo.java
源碼以下:
- package ni.demo.sharedpreferences;
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.content.SharedPreferences.Editor;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.Toast;
- public class SharedPreferencesDemo extends Activity {
- public static final String MY_PREFERENCES = "MY_PREFERENCES"; //Preferences文件的名稱
- public static final String MY_ACCOUNT = "MY_ACCOUNT"; //
- public static final String MY_PASSWORD = "MY_PASSWORD";
-
- private EditText edtAccount;
- private EditText edtPassword;
- private Button btnClear;
- private Button btnExit;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- edtAccount = (EditText)findViewById(R.id.edtAccount);
- edtPassword = (EditText)findViewById(R.id.edtPassword);
- //獲取名字爲「MY_PREFERENCES」的參數文件對象,並得到MYACCOUNT、MY_PASSWORD元素的值。
- SharedPreferences sp = this.getSharedPreferences(MY_PREFERENCES, 0);
- String account = sp.getString(MY_ACCOUNT, "");
- String password = sp.getString(MY_PASSWORD, "");
- //對密碼進行AES解密
- try{
- password = AESEncryptor.decrypt("41227677", password);
- }catch(Exception ex){
- Toast.makeText(this, "獲取密碼時產生解密錯誤!", Toast.LENGTH_SHORT);
- password = "";
- }
- //將帳號和密碼顯示在EditText控件上。
- edtAccount.setText(account);
- edtPassword.setText(password);
-
- //獲取"清空"按鈕的對象,併爲其綁定監聽器,如被點擊則清空帳號和密碼控件的值。
- btnClear = (Button)findViewById(R.id.btnClear);
- btnClear.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View arg0) {
- edtAccount.setText("");
- edtPassword.setText("");
- }
- });
- //獲取「退出」按鈕的對象,併爲其綁定監聽,如被點擊則退出程序。
- btnExit = (Button)findViewById(R.id.btnExit);
- btnExit.setOnClickListener(new OnClickListener(){
- @Override
- public void onClick(View arg0) {
- SharedPreferencesDemo.this.finish();
- }
- });
- }
- @Override
- protected void onStop() {
- super.onStop();
- //得到帳號、密碼控件的值,並使用AES加密算法給密碼加密。
- String account = edtAccount.getText().toString();
- String password = edtPassword.getText().toString();
- try{
- password = AESEncryptor.encrypt("41227677", password);
- }catch(Exception ex){
- Toast.makeText(this, "給密碼加密時產生錯誤!", Toast.LENGTH_SHORT);
- password = "";
- }
- //獲取名字爲「MY_PREFERENCES」的參數文件對象。
- SharedPreferences sp = this.getSharedPreferences(MY_PREFERENCES, 0);
- //使用Editor接口修改SharedPreferences中的值並提交。
- Editor editor = sp.edit();
- editor.putString(MY_ACCOUNT, account);
- editor.putString(MY_PASSWORD,password);
- editor.commit();
- }
-
-
- }
(5)效果測試
首先,在AVD咱們能夠看到以下界面,在兩個控件上咱們分別輸入abc和123456。
接着,咱們打開DDMS的File Explore能夠看到在data->data->ni->shared_prefs下面產生了一個名字叫作MY_PREFERENCES.xml的文件,該文件就是用來存儲咱們剛纔設置的帳號和密碼。
將其導出,並打開,能夠看到以下內容:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="MY_ACCOUNT">abc</string>
<string name="MY_PASSWORD">04B75FAD36E907BE50CE3222B0052B79</string>
</map>
這說明咱們能夠成功將帳號和加密後的密碼保存下來了。
最後,咱們點擊「退出」按鈕將應用程序結束掉,再從新打開。咱們又再次看到咱們退出前的界面,帳號密碼已經被從新讀取出來。
文章的最後,咱們進入Android API手冊,看看關於SharedPreferences的介紹:
Interface for accessing and modifying preference data returned by getSharedPreferences(String, int). For any particular set of preferences, there is a single instance of this class that all clients share. Modifications to the preferences must go through an SharedPreferences.Editor object to ensure the preference values remain in a consistent state and control when they are committed to storage.
SharedPreferences是一個用來訪問和修改選項數據的接口,經過getSharedPreferences(Stirng,int)來得到該接口。對於任何特別的選項集,只能有一個實例供全部客戶端共享。針對選項參數的修改必須經過一個SharedPreferences.Editor對象來進行,以保證全部的選項值保持在一個始終如一的狀態,而且經過該對象提交存儲。
可見,SharedPreferences操做選項文件時是線程安全的。 java