作为一个完整的应用程序,数据存储操作是必不可少的。因此,Android系统一共提供了四种数据存储方式。分别是:
1 SharePreference
2 SQLite
3 Content Provider
4 File
由于Android系统中,数据基本都是私有的,都是存放于“data/data/程序包名”目录下,所以要实现数据共享,正确方式是使用Content Provider。
SQLite:
SQLite是一个轻量级的数据库,支持基本SQL语法,是常被采用的一种数据存储方式。Android为此数据库提供了一个名为SQLiteDatabase的类,封装了一些操作数据库的API。
SQlite -- ANDROID数据库编程
sqlite是D.Richard Hipp用C语言编写的一款开源的轻量级嵌入式数据库,但比起前面几种存储数据方式确实重量级的。
它具有很多优点,比如:
1.轻量级
不同于sql server,oracle,mysql的c/s模式,这个数据库不存在客户端、服务器,只需要呆上他的一个动态库,就可以使用全部功能,是一个是进程内的数据库引擎。尺寸相当小。
2.独立性
数据库的核心引擎不需要第三方支持,也不需要安装此数据库。部署节约时间。
3.隔离性
sqlite数据库的所有内容(表、试图、触发器等)都包含在一个文件内,方便管理。
4.跨平台
pc上的系统外,Android、window mobile、sybian、palm等都可以使用。
5.多语言接口
支持主流的编程语言,c/c++,java,python,.net,ruby,perl等。
6.安全性
对于sqlite数据库的访问机制使用了共享锁和独占锁机制,同一时间,只能由占用独占锁的应用访问读写数据。其他进程不能执行读写操作,这就避免了类似读脏数据之类的不安全事件。
想了解sqlite更多情况请访问官网:http://www.sqlite.org
下面是在android平台数据库操作的详细代码:
- // 创建和打开数据库
- SQLiteDatabase mSQLiteDatabase = this.openOrCreateDatabase("dbname.db", MODE_PRIVATE, null);
- // 使用sql语句创建表
- string sql_create_db = “CREATE TABLE table_name(_id INTEGER PRIMARY KEY, num INTEGER, data TEXT)";
- mSQLiteDatabase.exeSQL(CREATE_TABLE);
- // 向表里添加数据(2种方法)
- // 1.使用ContentValues
- ContantValues cv = new ContantValues();
- cv.put(TABLE_NUM, 1); // 插入字段名TABLE_NUM自定义
- cv.put(TABLE_DATA, "test"); // 字段名TABLE_DATA自定义
- mSQLiteDatabase.insert(TABLE_NAME, null, cv);
- // 2.使用sql语句
- string sql_insert = "INSERT INTO tablename(_id, num, data) values(1, 1, 'test')";
- // 删除数据
- string sql_delete ="DELETE FROM tablename WHERE _id=1";
- mSQLiteDatabase.execSQL(sql_delete);
- // 修改表中的数据
- ContentValues cv = new ContentValues();
- cv.put(TABLE_NUM, 1); // 修改字段为TABLE_NUM的数据
- cv.put(TABLE_DATA, "ceshi"): // 修改字段为TABLE_DATA的数据
- mSQLiteDatabase.update("tablename", cv, "num " + "=" + Integer.toString(0), null);
- // 关闭数据库
- mSQLiteDatabase.close();
- // 删除指定表
- mSQLiteDatabase.execSQL("DROP TABLE tablename");
- // 删除数据库
- mSQLiteDatabase.deleteDatabase("databasename.db");
- // 查询表中的数据,这里给出一段代码
- // 使用Cursor对象查询数据
- Cursor cursor = mSQLiteDatabase.rawQuery("select * from table", null);
- if(cursor != null){
- if(cursor.moveToFirst()){
- do{
- int numColumn = cursor.getColumnIndex("num");
- int num = cursor.getInt(numColumn);
- }while(cursor.moveToNext());
- }
- }
扩展学习:
数据库文件仍然在/data/data/<package_name>/的database目录下。
有时会把这些方法封装成一个类用于通用编程,这个类一般叫SQLiteOpenHelper。明天附上一份代码。
- package mars.Activity16.db;
- import android.content.ContentValues;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.SQLException;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- public class MyDatabaseAdapter {
- // 打印的log
- private static final String TAG = "MyDatabaseAdapter";
- // 表中的一个字段名
- public static final String KEY_ID = "_id";
- // 编号
- public static final String KEY_NUM = "num";
- // 另一个字段名
- public static final String KEY_DATA = "data";
- // 数据库名称
- public static final String DB_NAME = "Example.db";
- // 数据表名
- public static final String DB_TABLE_NAME = "table_name";
- // 版本号
- public static final int DB_VERSION = 1;
- // 建表的sql语句
- public static final String DB_CREATE_SQL = "CREATE TABLE "
- + DB_TABLE_NAME + " ("
- + KEY_ID +" INTEGER PRIMARY KEY,"
- + KEY_NUM +" INTEGER,"
- + KEY_DATA + " TEXT)";
- // 本类中要使用的Context
- Context mContext = null;
- // 执行open()打开数据库时,保存返回的数据库对象
- private SQLiteDatabase mSQLiteDatabase = null;
- // 再声明一个继承自SQLiteOpenHelper对象
- private DatabaseHelper mDatabaseHelper = null;
- // 构造
- public MyDatabaseAdapter(Context context){
- mContext = context;
- }
- // 打开数据库
- public void open() throws SQLException{
- mDatabaseHelper = new DatabaseHelper(mContext);
- mSQLiteDatabase = mDatabaseHelper.getWritableDatabase();
- }
- // 关闭数据库
- public void close(){
- mDatabaseHelper.close();
- }
- // 插入一条数据
- public long insertData(int num, String data){
- ContentValues initialValues = new ContentValues();
- initialValues.put(KEY_NUM, num);
- initialValues.put(KEY_DATA, data);
- return mSQLiteDatabase.insert(DB_TABLE_NAME, KEY_ID, initialValues);
- }
- // 删除一条数据
- public boolean deleteData(long rowId){
- return mSQLiteDatabase.delete(DB_TABLE_NAME, KEY_ID+"="+rowId, null) > 0;
- }
- // 通过Cursor查询所有数据
- public Cursor fetchAllData(){
- return mSQLiteDatabase.query(DB_TABLE_NAME, new String[]{KEY_ID, KEY_DATA}, null, null, null, null, null);
- }
- // 查询指定数据
- public Cursor fetchData(long rowId) throws SQLException{
- Cursor mCursor = mSQLiteDatabase.query(true, DB_TABLE_NAME, new String[]{KEY_ID, KEY_DATA}, KEY_ID+"="+rowId, null, null, null, null, null);
- if(mCursor != null){
- mCursor.moveToFirst();
- }
- return mCursor;
- }
- // 更新一条数据
- public boolean updateData(long rowId, int num, String data){
- ContentValues values = new ContentValues();
- values.put(KEY_NUM, num);
- values.put(KEY_DATA, data);
- return (mSQLiteDatabase.update(DB_TABLE_NAME, values, KEY_ID+"="+rowId, null) > 0);
- }
- // 自定义内部类,用于简化SQLiteOpenHelper对象的使用
- private static class DatabaseHelper extends SQLiteOpenHelper{
- public DatabaseHelper(Context mContext) {
- // TODO Auto-generated constructor stub
- super(mContext, DB_NAME, null, DB_VERSION);
- }
- @Override
- public void onCreate(SQLiteDatabase db) {
- // TODO Auto-generated method stub
- db.execSQL(DB_CREATE_SQL);
- }
- // 升级数据库
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- // TODO Auto-generated method stub
- db.execSQL("DROP TABLE IF EXISTS notes");
- onCreate(db);
- }
- }
- }
SharedPreference:
除SQLite数据库外,另一种常用的数据存储方式,其本质就是一个xml文件,常用于存储较简单的参数设置。
- boolean mbMusic = false;
- SharedPreferences settings = getPreferences(Activity.MODE_PRIVATE); // 获取Preferences对象。
- sharedPreferences.Editor editor = settings.editor(); //编辑对象
- mbMusic = editor.getBoolean("bmusic"); // 获得值
- editor.putBoolean("bmusic", mbMusic); // 添加值
扩展学习:
这些数据会保存在/data/data目录下的应用程序的shared_prefs文件夹的一个xml文件。
File:
即常说的文件(I/O)存储方法,常用语存储大数量的数据,但是缺点是更新数据将是一件困难的事情。
学过java的应该懂的!!! ~
- boolean mbMusic = false;
- Properties properties = new Properties(); // 构建Properties对象
- FileInputStream stream = this.openFileInput("music.cfg"); // 打开文件,形成文件输入流
- // 读取数据
- properties.load(stream); // 读取文件
- mbMusic = boolean.valueOf(Properties.get("bmusic").toString());
- // 保存数据
- properties.put("bmusic", String.valueOf(mbmusic)); // 把一个数据打包成properties
- FileOutputStream stream = this.openFileOutput("music.cfg", Context.MODE_WORLD_WRITEABLE);
- properties.store(stream,"");// 存入文件中
扩展学习:
如果文件保存在SD卡上,注意配置AndroidMainifest.xml中的权限。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
默认状态下文件是不能在应用程序之间共享的。通过load()方法可以打开文件,通过deleteFile方法可以删除指定的文件。
即使使用绝对路径也不可以实现应用程序共享文件。
默认文件会保存在/data/data目录下的应用程序的shared_prefs文件夹的的files文件夹下。
另外如果需要初始化应用程序时加载一个文件也可以在res/raw/tempFile中建立一个static文件,通过Resources.openRawResource(R.raw.文件名)同样返回一个InputStream对象,读取文件内容。
ContentProvider:
Android系统中能实现所有应用程序共享的一种数据存储方式,由于数据通常在各应用间的是互相私密的,所以此存储方式较少使用,但是其又是必不可少的一种存储方式。例如音频,视频,图片和通讯录,一般都可以采用此种方式进行存储。每个ContentProvider都会对外提供一个公共的URI(包装成Uri对象),如果应用程序有数据需要共享时,就需要使用ContentProvider为这些数据定义一个URI,然后其他的应用程序就通过Content Provider传入这个URI来对数据进行操作。
转自百度经验