【
Android 中數據的本地存儲
存儲方式:
一、SharedPreferences 輕量級存儲
二、文件存儲
1. 內部存儲(存儲位置爲機身內存)
2. 外部存儲(存儲位置爲sd卡中)
三、數據庫
四、網絡
】
1.1 SharedPreferences 輕量級存儲
【
存儲特點:
1. 以鍵值對的特點存儲數據
2. 存儲位置固定:data/data/程序包名/shared_prefs
3. 存儲的文件類型(文件後綴)固定: xml文件
4. 存儲的數據類型固定,只能是:boolean,float,int,long,String,Set<String>
實現方式:
存儲:
1. 創建一個SharedPreferences對象
2. 通過pref對象獲取Editor對象,通過該對象調用存儲數據的方法
3. 通過Editor對象調用put方法存入數據
4. 通過commit或者apply方法進行提交,否則數據存不進去
5. //1. 創建一個SharedPreferences對象
6. /*
7. * 可以通過getSharedPreferences方法或者getPreferences方法
8. * 獲取對象
9. * 區別在於:getPreferences方法無法自定義文件名
10. * getSharedPreferences方法參數:
11. * 1. 自定義文件名
12. * 2. 存儲的文件類型,如,只讀,只寫,私有等
13. *
14. * */
15. SharedPreferencespref = getSharedPreferences("ay.txt", Context.MODE_PRIVATE);
16.
17. //2. 通過pref對象獲取Editor對象,通過該對象調用存儲數據的方法
18. Editoredit = pref.edit();
19.
20. //3. 通過Editor對象調用put方法存入數據
21. edit.putBoolean("bool", true);
22. edit.putString("str", "llalalla");
23.
24. Set<String>set = new HashSet<String>();
25. set.add("abc");
26. set.add("bcd");
27. set.add("eee");
28.
29. edit.putStringSet("set", set);
30.
31. //4. 通過commit或者apply方法進行提交,否則數據存不進去
32. /*
33. * 區別:commit是在主線程中存入數據
34. * apply是異步存入數據,即在子線程中存入數據
35. * */
36. edit.commit();
讀取:
1. 創建一個SharedPreferences對象
2. 通過pref對象調用get方法取出數據
//1.創建一個SharedPreferences對象
SharedPreferences pref1 = getSharedPreferences("ay.txt", Context.MODE_PRIVATE);
//2. 通過pref對象調用get方法取出數據
/*
* 參數一:
* 要讀取的數據在鍵值對中對應的key
* 參數二:
* 默認值,當文件不存在或者key寫錯時,getBoolean方法的返回值爲此默認值
* */
boolean b = pref1.getBoolean("bool", false);
String s = pref1.getString("str", "moren");
Set<String> ss = pref1.getStringSet("set", new HashSet<String>());
Log.i("===", "!!! "+b+" "+s+" "+ss.toString());
注:當通過SharedPreferences對象存入和讀取數據時,可以使用同一個SharedPreferences對象同時執行存入和讀取操作
】
1.1.1 示例:引導頁與記住用戶名操作
【
public class WelcomeActivity extends Activity {
private SharedPreferences pref ;
/*
* 只有當程序第一次運行時顯示的引導頁面
*
* 實現思路:
* 判斷是否是第一次登錄
* 如果是,正常顯示本頁面,如果不是,直接由本頁面跳轉到下一個頁面
* */
@Override
protected voidonCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
pref =getSharedPreferences("login", MODE_PRIVATE);
boolean flag = pref.getBoolean("key", false);
if(flag){ //有原始存入的值就不是第一次登錄
startActivity(new Intent(WelcomeActivity.this,MainActivity.class));
finish();
}
setContentView(R.layout.welcome);
}
public voidclick(View v){
pref.edit().putBoolean("key",true).commit();
startActivity(new Intent(WelcomeActivity.this,MainActivity.class));
finish();
}
}
public class MainActivity extends Activity {
/*
* 實現記住用戶功能
**/
private EditText name,pass;
private Button but;
private CheckBox cb;
boolean flag;
private SharedPreferences pref;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pref = getSharedPreferences("name", Context.MODE_PRIVATE);
initView();
//初始化情況下決定是否要顯示用戶名
Stringss = pref.getString("user",null);
if(ss != null){
name.setText(ss);
cb.setChecked(true);
}
}
private voidinitView() {
// TODO Auto-generated method stub
name =(EditText) this.findViewById(R.id.editText1_xe);
pass =(EditText) this.findViewById(R.id.editText2_xe);
cb=(CheckBox) this.findViewById(R.id.checkBox1_xe);
but=(Button) this.findViewById(R.id.button2_xe);
}
public voidclick(View v){
switch (v.getId()) {
case R.id.button1_xe: //登錄
if(cb.isChecked()){
Strings = name.getText().toString();
pref.edit().putString("user",s).commit();
}else{
pref.edit().clear().commit();
}
finish();
break;
case R.id.button2_xe://控制密碼的顯示與隱藏
if(flag){
//顯示密碼操作
flag = false;
pass.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
but.setText("顯示密碼");
}else{
flag= true;
pass.setTransformationMethod(PasswordTransformationMethod.getInstance());
but.setText("顯示密碼");
}
break;
}
}
}
】
1.2 文件存儲
【
共同特點:
存入數據,讀取數據時使用IO流進行的操作
】
1.2.1 內部存儲
【
1. 存儲位置固定:data/data/程序包名/files
2. 存儲的文件類型可任意指定
3. 存儲的數據類型不固定,可以存儲任意的圖片,文字等數據
實現步驟:
存入:
1. 獲取用於寫入數據的Output流對象
2. 通過流對象調用write方法寫入數據
3. 關閉流對象
//1.獲取用於寫入數據的Output流對象
/*
* 參數一:指定生成的文件名稱,
* 二:文件的類型
* */
os = openFileOutput("ay.txt", Context.MODE_APPEND);
//2. 通過流對象調用write方法寫入數據
os.write("多卡佛肚佛IDUFO薩迪UFOis度覅偶愛哦福".getBytes());
//3.關閉流對象
os.close();
讀取:
1. 獲取用於讀取數據的Input流對象
2. 通過流對象的read方法讀取數據
3. 關閉流對象
//1.獲取用於讀取數據的Input流對象
InputStream is = openFileInput("ay.txt");
//2. 通過流對象的read方法讀取數據
byte[] by =new byte[1024];
int num=0;
StringBuilder builder = new StringBuilder();
while ((num = is.read(by)) != -1) {
builder.append(new String(by,0,num));
}
Log.i("===", "-====getString "+builder.toString());
//3. 關閉流對象
is.close();
】
1.2.1.1 示例代碼:文件和圖片的存入和讀取
【
public class MainActivity extends Activity {
private ImageView img_read_n;
@Override
protected voidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img_read_n = (ImageView) this.findViewById(R.id.img_read_n);
}
public voidclick(View v) {
switch (v.getId()) {
case R.id.btn_n_cun:// 向機身內存中存儲文件數據
storyFile();
break;
case R.id.btn_n_du:// 讀取機身內存中指定的文件
readFile();
break;
case R.id.btn_n_drin:// 將drawable文件夾中的圖片存入本地
storeDrawableInFile();
break;
case R.id.btn_n_drread:// 讀取機身內存中的圖片
readDrawableInFile();
break;
}
}
/**
* 讀取機身內存中的圖片
*/
private voidreadDrawableInFile() {
// 讀取並顯示機身內存中圖片的方式一:
/*
* InputStream is = null ; try { is=openFileInput("dr.jpg");
*img_read_n.setImageBitmap(BitmapFactory.decodeStream(is)); }
* catch (FileNotFoundException e) { // TODO Auto-generated catch
* block e.printStackTrace(); }finally{ if(is!= null){ try {
* is.close(); is =null; } catch (IOExceptione) { // TODO
* Auto-generated catch blocke.printStackTrace(); } } }
*/
// 讀取並顯示機身內存中圖片的方式二:
img_read_n.setImageURI(Uri.parse("file://"
+getFilesDir().getAbsolutePath() + "/dr.jpg"));
}
/**
* 將drawable文件夾中的圖片存入本地
*/
private voidstoreDrawableInFile() {
/*
* compress 壓縮方法作用:將bit圖片中的數據壓縮寫入到參數三指定的流中
*/
Bitmap bit = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_launcher);
OutputStream oo = null;
try {
oo = openFileOutput("dr.jpg", Context.MODE_PRIVATE);
/*
* 1. 圖片的解析格式 2. 生成的圖片的質量,範圍0到100,質量越高,圖片越清晰但是此質量值對解析格式爲png的無效
*/
bit.compress(CompressFormat.JPEG, 20, oo);
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (oo != null){
try {
oo.close();
oo= null;
}catch (IOException e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 讀取機身內存中指定的文件
*/
private voidreadFile() {
FileInputStreamfis = null;
try {
fis= openFileInput("xys.txt");
byte[] buf = newbyte[1024];
int num = 0;
StringBufferbuffer = new StringBuffer();
while ((num = fis.read(buf)) != -1) {
buffer.append(new String(buf, 0, num));
}
Toast.makeText(this, buffer.toString(), Toast.LENGTH_SHORT)
.show();
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (fis != null){
try {
fis.close();
fis= null;
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 向機身內存中存儲文件數據
*/
private voidstoryFile() {
FileOutputStreamout = null;
try {
out= openFileOutput("xys.txt",Context.MODE_PRIVATE);
out.write("的附件見客戶的關鍵是開發教科書的反饋見多識廣".getBytes());
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (out != null){
try {
out.close();
out= null;
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
】
1.2.2 外部存儲
【
1. 存儲位置部分固定:手機的外部存儲卡,sd卡中, 默認的sd路徑: /mnt/sdcard
2. 存儲的文件類型可任意指定
3. 存儲的數據類型不固定,可以存儲任意的圖片,文字等數據
實現方式:
存入:
通過指定sd卡文件路徑寫獲取對應的FileOutputStream寫入數據即可
FileOutputStreamfos = new FileOutputStream("/mnt/sdcard/aa.txt");
讀取:
通過指定的文件路徑獲取對應FileInputStream讀取數據即可
FileInputStream fis = newFileInputStream("/mnt/sdcard/aa.txt");
Sd卡中常用的操作方法:
獲取SD卡的狀態:Environment.getExternalStorageState()
獲取SD卡的根路徑:Environment.getExternalStorageDirectory()
訪問特定類型的目錄:Environment.getExternalStoragePublicDirectory(String type)
DIRECTORY_ALARMS // 警報的鈴聲
DIRECTORY_DCIM // 相機拍攝的圖片和視頻保存的位置
DIRECTORY_DOWNLOADS // 下載文件保存的位置
DIRECTORY_MOVIES // 電影保存的位置, 比如 通過google play下載的電影
DIRECTORY_MUSIC // 音樂保存的位置
DIRECTORY_NOTIFICATIONS // 通知音保存的位置
DIRECTORY_PICTURES // 下載的圖片保存的位置
DIRECTORY_PODCASTS // 用於保存podcast(博客)的音頻文件
DIRECTORY_RINGTONES // 保存鈴聲的位置
訪問內存狀態
StatFs:文件內存狀態類
示例代碼
// 獲取SD卡根目錄
File path =Environment.getExternalStorageDirectory();
// 獲取指定目錄下的內存存儲狀態
StatFs stat =new StatFs(path.getPath());
// 獲取單個扇區的大小
long blockSize= stat.getBlockSize();
// 獲取扇區的數量
longtotalBlocks = stat.getBlockCount();
// 獲取可以使用的扇區數量
longavailableBlocks = stat.getAvailableBlocks();
// 可用空間 = 扇區的大小 + 可用的扇區
longavailableSize = blockSize * availableBlocks;
// 總空間 = 扇區的總數 * 扇區的大小
long totalSize= blockSize * totalBlocks;
// 格式化文件大小的格式
Log.i("oye","可用空間 = " + Formatter.formatFileSize(this, availableSize));
Log.i("oye","總空間 = " + Formatter.formatFileSize(this, totalSize));
注意:操作SDCard需要添加權限:
<!-- 向sd卡中添加寫入數據的權限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 從sd卡中讀取數據的權限-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!-- 在sd卡中創建或刪除文件夾及文件-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
】