android数据管理方法,Android数据存储方式

一、使用SharedPreferences存储数据

默认存储路径:/data/data//shared_prefs

SharedPreferences是一个较轻量级的存储数据的方法,适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型、基本类型的值。

核心原理:保存基于XML文件存储的key-value键值对数据,通常用来存储一些简单的配置信息。通过DDMS的File Explorer面板,展开文件浏览树,很明显SharedPreferences数据总是存储在/data/data//shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.edit()获取的内部接口Editor对象实现。 SharedPreferences本身是一 个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(String name, int mode)方法来获取SharedPreferences实例,

该方法中name表示要操作的xml文件名,第二个参数为设置读写模式,有以下三种选择:

Context.MODE_PRIVATE: 指定该SharedPreferences数据只能被本应用程序读、写。

Context.MODE_WORLD_READABLE: 指定该SharedPreferences数据能被其他应用程序读,但不能写。

Context.MODE_WORLD_WRITEABLE: 指定该SharedPreferences数据能被其他应用程序读,写。

而编辑接口Editor有如下主要重要方法:

SharedPreferences.Editor clear():清空SharedPreferences里所有数据

** SharedPreferences.Editor putXxx(String key , xxx value):** 向SharedPreferences存入指定key对应的数据,其中xxx 可以是boolean,float,int等各种基本类型据

** SharedPreferences.Editor remove()**: 删除SharedPreferences中指定key对应的数据项

** boolean commit()**: 当Editor编辑完成后,使用该方法提交修改

读写其他应用的SharedPreferences: 步骤如下

在创建SharedPreferences时,指定MODE_WORLD_READABLE模式,表明该SharedPreferences数据可以被其他程序读取

创建其他应用程序对应的Context:

Context pvCount = createPackageContext("com.tony.app",

Context.CONTEXT_IGNORE_SECURITY);这里的com.tony.app就是其他程序的包名

使用其他程序的Context获取对应的SharedPreferences

SharedPreferences read = pvCount.getSharedPreferences("lock",

Context.MODE_WORLD_READABLE);

如果是写入数据,使用Editor接口即可,所有其他操作均和前面一致。

SharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。但是SharedPreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。另外需要注意的一点是sharePreference在多进程的情况下会失效。

二、SQLite数据库存储数据

默认存储路径:/data/data//databases

SQLite是轻量级嵌入式数据库引擎,它支持 SQL 语言,并且只利用很少的内存就有很好的性能。现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据。

SQLiteDatabase类为我们提供了很多种方法,上面的代码中基本上囊括了大部分的数据库操作;对于添加、更新和删除来说,我们都可以使用

1 db.executeSQL(String sql);

2 db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//打开或创建test.db数据库

SQLiteDatabase db = openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null);

db.execSQL("DROP TABLE IF EXISTS person");

//创建person表

db.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age SMALLINT)");

Person person = new Person();

person.name = "john";

person.age = 30;

//插入数据

db.execSQL("INSERT INTO person VALUES (NULL, ?, ?)", new Object[]{person.name, person.age});

person.name = "david";

person.age = 33;

//ContentValues以键值对的形式存放数据

ContentValues cv = new ContentValues();

cv.put("name", person.name);

cv.put("age", person.age);

//插入ContentValues中的数据

db.insert("person", null, cv);

cv = new ContentValues();

cv.put("age", 35);

//更新数据

db.update("person", cv, "name = ?", new String[]{"john"});

Cursor c = db.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});

while (c.moveToNext()) {

int _id = c.getInt(c.getColumnIndex("_id"));

String name = c.getString(c.getColumnIndex("name"));

int age = c.getInt(c.getColumnIndex("age"));

Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age);

}

c.close();

//删除数据

db.delete("person", "age < ?", new String[]{"35"});

//关闭当前数据库

db.close();

//删除test.db数据库

// deleteDatabase("test.db");

}

在执行完上面的代码后,系统就会在/data/data/[PACKAGE_NAME]/databases目录下生成一个“test.db”的数据库文件。

上面的代码中基本上囊括了大部分的数据库操作;对于添加、更新和删除来说,我们都可以使用

db.executeSQL(String sql);

db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集

来执行sql语句,

除了统一的形式之外,他们还有各自的操作方法:

db.insert(String table, String nullColumnHack, ContentValues values);

db.update(String table, Contentvalues values, String whereClause, String whereArgs);

db.delete(String table, String whereClause, String whereArgs);

以上三个方法的第一个参数都是表示要操作的表名;insert中的第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;insert中的第三个参数是ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表该列要插入的值;update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数whereClause表示WHERE表达式,比如“age > ? and age < ?”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数也是一样。

下面,我们就以一个实例来讲解具体的用法,我们新建一个名为db的项目,其中DBHelper继承了SQLiteOpenHelper,作为维护和管理数据库的基类,DBManager是建立在DBHelper之上,封装了常用的业务方法,Person是我们的person表对应的JavaBean,MainActivity就是我们显示的界面。

public class DBHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "test.db";

private static final int DATABASE_VERSION = 1;

public DBHelper(Context context) {

//CursorFactory设置为null,使用默认值

super(context, DATABASE_NAME, null, DATABASE_VERSION);

}

//数据库第一次被创建时onCreate会被调用

@Override

public void onCreate(SQLiteDatabase db) {

db.execSQL("CREATE TABLE IF NOT EXISTS person" +

"(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, info TEXT)");

}

//如果DATABASE_VERSION值被改为2,系统发现现有数据库版本不同,即会调用onUpgrade

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

db.execSQL("ALTER TABLE person ADD COLUMN other STRING");

}

}

数据库第一次创建时onCreate方法会被调用,我们可以执行创建表的语句,当系统发现版本变化之后,会调用onUpgrade方法,我们可以执行修改表结构等语句。

为了方便我们面向对象的使用数据,我们建一个Person类,对应person表中的字段,如下:

public class Person {

public int _id;

public String name;

public int age;

public String info;

public Person() {

}

public Person(String name, int age, String info) {

this.name = name;

this.age = age;

this.info = info;

}

}

然后,我们需要一个DBManager,来封装我们所有的业务方法,代码如下:

public class DBManager {

private DBHelper helper;

private SQLiteDatabase db;

public DBManager(Context context) {

helper = new DBHelper(context);

//因为getWritableDatabase内部调用了mContext.openOrCreateDatabase(mName, 0, mFactory);

//所以要确保context已初始化,我们可以把实例化DBManager的步骤放在Activity的onCreate里

db = helper.getWritableDatabase();

}

/**

* add persons

* @param persons

*/

public void add(List persons) {

db.beginTransaction(); //开始事务

try {

for (Person person : persons) {

db.execSQL("INSERT INTO person VALUES(null, ?, ?, ?)", new Object[]{person.name, person.age, person.info});

}

db.setTransactionSuccessful(); //设置事务成功完成

} finally {

db.endTransaction(); //结束事务

}

}

/**

* update person's age

* @param person

*/

public void updateAge(Person person) {

ContentValues cv = new ContentValues();

cv.put("age", person.age);

db.update("person", cv, "name = ?", new String[]{person.name});

}

/**

* delete old person

* @param person

*/

public void deleteOldPerson(Person person) {

db.delete("person", "age >= ?", new String[]{String.valueOf(person.age)});

}

/**

* query all persons, return list

* @return List

*/

public List query() {

ArrayList persons = new ArrayList();

Cursor c = queryTheCursor();

while (c.moveToNext()) {

Person person = new Person();

person._id = c.getInt(c.getColumnIndex("_id"));

person.name = c.getString(c.getColumnIndex("name"));

person.age = c.getInt(c.getColumnIndex("age"));

person.info = c.getString(c.getColumnIndex("info"));

persons.add(person);

}

c.close();

return persons;

}

/**

* query all persons, return cursor

* @return Cursor

*/

public Cursor queryTheCursor() {

Cursor c = db.rawQuery("SELECT * FROM person", null);

return c;

}

/**

* close database

*/

public void closeDB() {

db.close();

}

}

我们在DBManager构造方法中实例化DBHelper并获取一个SQLiteDatabase对象,作为整个应用的数据库实例;在添加多个Person信息时,我们采用了事务处理,确保数据完整性;最后我们提供了一个closeDB方法,释放数据库资源,这一个步骤在我们整个应用关闭时执行,这个环节容易被忘记

现在Android在SQLite数据存储方面出现了很多的ORM框架:ORMLite、greendao、ormndroid、androrm、ActiveAndroid,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。这些都极大的提高了我们的开发数据库的效率,也值得我们深入学习。

三、文件存储数据

默认存储路径:/data/data//files

核心原理: Context提供了两个方法来打开数据文件里的文件IO流 FileInputStream openFileInput(String name); FileOutputStream(String name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。具体有以下值可选:

MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可 以使用Context.MODE_APPEND

MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;

MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。

除此之外,Context还提供了如下几个重要的方法:

getDir(String name , int mode):在应用程序的数据文件夹下获取或者创建name对应的子目录

File getFilesDir():获取该应用程序的数据文件夹得绝对路径

String[] fileList():返回该应用数据文件夹的全部文件

写入文件:

public void save(){

String data = "save something here";

FileOutputStream out = null;

ButteredWriter writer = null;

try{

out = openFileOutput("data",Context.MODE_PRIVATE);

writer = new ButteredWriter(new OutputSreamWriter(out));

writer.write(data);

}catch(IOException e){

e.printStackTrace();

}finally{

try{

if(writer!=null){

writer.close();

}

}catch(IOException e){

e.printStackTrace();

}

}

读取文件数据:

public String load(){

FileInputStream in = null;

ButteredReader reader = null;

StringBuilder builder = new StringBuilder();

try{

in = openFileInput("data");

reader = new ButteredReader(new InputStreamReader(in));

String line= "";

while((line = reader.readline()) != null){

builder.append();

}

}catch(IOException e){

e.printStackTrace();

}finally{

if(reader != null){

try{

reader.close();

}catch(IOException e){

e.printStackTrace();

}

}

}

}

读写sdcard上的文件

其中读写步骤按如下进行:

1、调用Environment的getExternalStorageState()方法判断手机上是否插了sd卡,且应用程序具有读写SD卡的权限,如下代码将返回true

Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

2、调用Environment.getExternalStorageDirectory()方法来获取外部存储器,也就是SD卡的目录,或者使用"/mnt/sdcard/"目录

3、使用IO流操作SD卡上的文件

注意点:手机应该已插入SD卡,对于模拟器而言,可通过mksdcard命令来创建虚拟存储卡

必须在AndroidManifest.xml上配置读写SD卡的权限

四、ContentProvider存储数据

ContentProvider主要用于不同的程序之间实现数据共享的功能。详见Android四大组件介绍的内容

五、网络存储

这个很好理解,就是将数据上传到服务器,在需要的时候再将它通过网络读取下来即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值