官网链接

http://developer.android.com/training/basics/data-storage/index.html

一、保存key-value集

key-value 对广大coder来说已经再熟悉不过了。

为了方便使用者快捷的存取数据在andorid中key-value保存在一个文件中的。1.1 获取SharedPreferences实例

在Activity中可以直接获得SharedPreferences实例,否则需要先得到Activity实例

SharedPreferences preferences = getPreferences(Context.MODE_PRIVATE);SharedPreferences sharedPreferences = getSharedPreferences("sharedFile", Context.MODE_PRIVATE);

两种方式有区别,之前不是说这些key-value数据存放在文件中吗,所以getPreferences是当前Activity实例的一个文件,而getSharedPreference是新建一个文件来存,所以需要提供一个名字。

第二个参数是模式的选择的,简单说点,MODE_PRIVATE是私有的,不给其它使用,还有比如MODE_WORLD_WRITEABLE则可以全局访问,据官网介绍甚至其它APP都可以使用哦,这个没有尝试。

1.2 读和写

很简单的API所以放一起写了,直接上代码

SharedPreferences preferences = getPreferences(Context.MODE_PRIVATE);preferences.edit().putString("key", "test").commit();String ret0=preferences.getString("key", "default");System.out.println("key -------------- " + ret0);SharedPreferences sharedPreferences = getSharedPreferences("sharedFile", Context.MODE_PRIVATE);sharedPreferences.edit().putString("key", "testShare").commit();String ret = sharedPreferences.getString("key", "default");System.out.println("shared key ------------- " + ret);

注意到了吗,是写System.out来输出的,通常android不用这种输出方式,因为文章还没有介绍到如何利用android的Log API来现实日志,所以先用着吧。

二、保存文件

2.1 选择内部还是外部的存储介质

所谓内存储是指机器本来的内存,我们通常叫机身内存。外部存储介质比如SD卡之类的。

为什么分为两部分呢,因为

在内部存储:

1.总是可用的

2.保存的文件通常只能它自己的APP可以访问

3.卸载APP的时候会连带删除APP的文件

外部存储

1.不总是肯定,因为在某些时候你可能取出SD卡

2.因为是全局可读的,所以保存在这里的文件可能会在你的控制之外。

3.卸载APP的时候,系统会删除你用getExternalFilesDir()保存的文件,其它方式保存的不会删除。

2.2 为外部存储设置权限

我们通过在Manifest 文件中设置外部存储的权限

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="cn.tang.test"    android:versionCode="1"    android:versionName="1.0" >    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    ......</manifest>
这是写的权限,如果是读权限 WRITE_EXTERNAL_STORAGE

2.3 在内部存储中保存文件

可以通过以下两种方式来得到一个文件

getFilesDir()

getCacheDir() 临时的缓存文件,系统内存不够时,可能会删除

//context.getFilesDir()File file = new File(context.getFilesDir(), filename);//context.getCacheDir() File file;    try {        String fileName = Uri.parse(url).getLastPathSegment();        file = File.createTempFile(fileName, null, context.getCacheDir());    catch (IOException e) {        // Error while creating file    }    return file;

向文件写数据利用到了文件流

String filename = "myfile";String string = "Hello world!";FileOutputStream outputStream;try {  outputStream = openFileOutput(filename, Context.MODE_PRIVATE);  outputStream.write(string.getBytes());  outputStream.close();} catch (Exception e) {  e.printStackTrace();}

2.4 在外部存储中保存文件

因为外部存储不一定总可用,所以我们需要判断可用的情况

/* Checks if external storage is available for read and write */public boolean isExternalStorageWritable() {    String state = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED.equals(state)) {        return true;    }    return false;}/* Checks if external storage is available to at least read */public boolean isExternalStorageReadable() {    String state = Environment.getExternalStorageState();    if (Environment.MEDIA_MOUNTED.equals(state) ||        Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {        return true;    }    return false;}

尽管在外部存储中的文件可以被用户和其它APP修改,android提供了两种类型的文件。

Public files 卸载APP后文件不会删除,比如照片信息

private files 卸载之后文件被删除,比如说额外的下载的资源文件

//公有的文件public File getAlbumStorageDir(String albumName) {    // Get the directory for the user's public pictures directory.     File file = new File(Environment.getExternalStoragePublicDirectory(            Environment.DIRECTORY_PICTURES), albumName);    if (!file.mkdirs()) {        Log.e(LOG_TAG, "Directory not created");    }    return file;}//私有的文件public File getAlbumStorageDir(Context context, String albumName) {    // Get the directory for the app's private pictures directory.     File file = new File(context.getExternalFilesDir(            Environment.DIRECTORY_PICTURES), albumName);    if (!file.mkdirs()) {        Log.e(LOG_TAG, "Directory not created");    }    return file;}

2.5 查询空闲空间

在程序运行时知道空闲空间在某些情况下可能会很有用,必须你下载一个较大文件的时候

android提供两个方法

getFreeSpace()

getTotalSpace()

2.6 删除一个文件

myFile.delete();myContext.deleteFile(fileName);

当app被卸载的时候,系统会按照下面的逻辑删除文件

1. 删除internal storage(内部存储)中保存的文件

2. 删除extenal storage(外部存储)中使用getExternalFilesDir()保存的文件

三、保存到数据库中

android有内嵌的数据库sqlite。

官网的文档关于这方面写的感觉有点啰嗦了,可能想让大家养成一个好的习惯吧。其实有超级简单的例子,可能在现阶段有些人还不想搞那么复杂来个简单的吧,我直接在Activity中写一个方法,然后再onCreate中调用它测试了一下。

private void dbtest() {SQLiteDatabase db = openOrCreateDatabase("my.db", Context.MODE_PRIVATE,null);db.execSQL("drop table if exists test");db.execSQL("create table test(id varchar,name varchar)");db.execSQL("insert into test values(?,?)", new Object[] { "id_1", "name_1" });Cursor cursor = db.rawQuery("select * from test where name =?",new String[] { "name_1" });while (cursor.moveToNext()) {String id = cursor.getString(cursor.getColumnIndex("id"));System.out.println("id =========== " + id);Log.i("db_target", "id \t" + id);}cursor.close();db.close();}
爽了一下之后开始跟着官网慢慢来吧。

3.1 定义Schema 和 Contract

所谓schema和Contract 其实是你的数据库和表的定义,他们叫的比较专业,我等通常叫创建数据库和表。

哎,谁谁谁,给创建的sql语句给我发一份....

public final class FeedReaderContract {public FeedReaderContract() {}public static abstract class FeedEntry implements BaseColumns {        public static final String TABLE_NAME = "entry";        public static final String COLUMN_NAME_ENTRY_ID = "entryid";        public static final String COLUMN_NAME_TITLE = "title";        public static final String COLUMN_NAME_SUBTITLE = "subtitle";    }}
理解为常量类,类中定义了一些数据库定义方面的常量。

3.2 使用SQL Helper 创建数据库

android提供了一个叫做SQLiteOpenHelper的类来帮助我们使用SQLite.

public class FeedReaderDbHelper extends SQLiteOpenHelper {public static final int DATABASE_VERSION = 1;public static final String DATABASE_NAME = "FeedReader.db";public FeedReaderDbHelper(Context context) {super(context, DATABASE_NAME, null, DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL(SQL_CREATE_ENTRIES);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL(SQL_DELETE_ENTRIES);        onCreate(db);}private static final String TEXT_TYPE = " TEXT";private static final String COMMA_SEP = ",";private static final String SQL_CREATE_ENTRIES = "CREATE TABLE "+ FeedEntry.TABLE_NAME + " (" + FeedEntry._ID+ " INTEGER PRIMARY KEY," + FeedEntry.COLUMN_NAME_ENTRY_ID+ TEXT_TYPE + COMMA_SEP + FeedEntry.COLUMN_NAME_TITLE + TEXT_TYPE+ COMMA_SEP + " )";private static final String SQL_DELETE_ENTRIES = "DROP TABLE IF EXISTS "+ FeedEntry.TABLE_NAME;}
根据以前的常量值,在这个类中,拼写了一些常用的SQL语句,为了方便看我放在了最后面。继承SQLiteOpenHelper之后,需要实现onCreate()和onUpdate()方法,这两个方法分别在第一次使用数据库时,和版本号改变后调用,所谓版本号改动就是DATABASE_VERSION值改变了,如果你的APP数据库表发生改变了,修改下这个版本号,系统在下次启动的时候会调用onUpdate()方法,然后我们在方法中做一些适应性的改变,上面例子中比较暴力,直接把以前的表删除了,建的新表。(对于这种情况我表示有点害怕,出问题别怪我,官网上就这么写的)

3.3 put/read/delete/update

增删该查,数据库四大神兵,必须得知道的

private void dbOperationTest() {FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(this);SQLiteDatabase wdb = mDbHelper.getWritableDatabase();SQLiteDatabase rdb = mDbHelper.getReadableDatabase();// putContentValues values = new ContentValues();values.put(FeedEntry.COLUMN_NAME_ENTRY_ID, "id_" + 0);values.put(FeedEntry.COLUMN_NAME_TITLE, "title_" + 0);long newRowId;newRowId = wdb.insert(FeedEntry.TABLE_NAME, null, values);// queryCursor cursor = rdb.query(FeedEntry.TABLE_NAME, // The table to querynew String[] { FeedEntry.COLUMN_NAME_ENTRY_ID,FeedEntry.COLUMN_NAME_TITLE }, // The columns to returnFeedEntry.COLUMN_NAME_TITLE +"=?", // The columns for the WHERE clausenew String[]{"title_"+0}, // The values for the WHERE clausenull, // don't group the rowsnull, // don't filter by row groupsFeedEntry.COLUMN_NAME_TITLE+" DESC" // The sort order);while (cursor.moveToNext()) {String id = cursor.getString(cursor.getColumnIndex(FeedEntry.COLUMN_NAME_ENTRY_ID));Log.i("db_target", "id \t" + id);}cursor.close();//deleteString selection = FeedEntry.COLUMN_NAME_ENTRY_ID + " LIKE ?";String[] selectionArgs = { "id_"+0 };wdb.delete(FeedEntry.TABLE_NAME, selection, selectionArgs);//udpateContentValues updateValues = new ContentValues();values.put(FeedEntry.COLUMN_NAME_TITLE, "title_2");int count = wdb.update(    FeedEntry.TABLE_NAME,    updateValues,    selection,    selectionArgs);//closerdb.close();wdb.close();}


更多相关文章

  1. android将图片保存到系统相册
  2. [安卓问题]如何制作Jar包并在android中调用jar包
  3. android adb project
  4. apk 反编译源码 资源文件
  5. 改变ProgressBar默认颜色
  6. Android(安卓)反编译Apk得到Java源代码
  7. android aidl出现无法import
  8. Android通过url下载文件到手机本地
  9. 烧板子流程

随机推荐

  1. Android中设置分割线
  2. Android平台开发-Android(安卓)keypad ma
  3. android studio上HierarchyViewer的使用
  4. 一些关于Activity的技巧
  5. android之Display.getRotation()_传感器
  6. Android数据库编程教程
  7. android Handler导致内存泄露分析
  8. Android中贪吃蛇游戏的学习(三)
  9. Android拖拽详解
  10. Android(安卓)am命令