一:文件存储
文件存储时Android中最基本的数据存储方式,他不对存储的内容进行任何格式化处理,所有的数据都是原封不动的保存在文件当中的,因为他比较适合存储一些简单的文本数据和二进制数据
如果需要使用文件存储的方式来保存一些较为复杂的数据结构,就需要定义一套自己的格式规范,方便之后将数据从文件当中重新解析出来.
存储方法:
(一)内部存储
// 将数据存储到指定的文件中
// name为文件名,mode为文件的操作模式
FileOutputStream fos = openFileOutput(String name,int mode);
// 读取指定文件中的数据
FileInputStream fis = openFileInput(String name);
mode的取值如下:
MODE_PRIVATE:该文件只能被当前程序读写 ; MODE_APPEND:该文件的内容可以追加; MODE_WORLD_READABLE:该文件的内容可以被其他程序读; MODE_WORLD_WRITEABLE:该文件的内容可以被其他程序写
注意:Android系统有一套自己的安全模型,默认情况下任何应用创建的文件都是私有的,其他程序无法访问。
1.写入文件步骤
String fileName = “data.txt”; // 文件名称
String content = “helloworld”; // 保存数据
FileOutputStream fos = openFileOutput(fileName, MODE_PRIVATE);
fos.write(content.getBytes()); //将数据写入文件中
fos.close(); //关闭输出流
2.读取文件步骤
String content = “”;
FileInputStream fis = null;
fis = openFileInput(“data.txt”); //获得文件输入流对象
byte[] buffer = new byte[fis.available()]; // 创建缓冲区,并获取文件长度
fis.read(buffer); // 将文件内容读取到buffer缓冲区
content = new String(buffer);//转换成字符串
fis.close(); //关闭输入流
3.实现存储和读取用户名和密码实例
创建UserInfoIO工具类,实现存储数据方法(saveUserInfo)和读取数据方法(getUserInfo)
public class UserInfoIO {
// 数据的写入
public static boolean saveUserInfo(String username, String password, Context context){
// openFileOutput(要操作的文件名,文件访问模式)
FileOutputStream fos = null;
String msg = null;
try { // 在操作文件的时候可能会报异常,需要进行捕获
fos = context.openFileOutput("MyData.txt",Context.MODE_PRIVATE);
msg = username + ":" + password;
// getBytes()将字符串转换为字节流
fos.write(msg.getBytes());
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
finally {
try {
fos.close(); // 流是系统中的稀缺资源,在使用完后要及时关闭
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 用户数据的读取
public static Map<String,String> getUserInfo(Context context){
// 获取文件输入流
FileInputStream fis = null;
try {
fis = context.openFileInput("MyData.txt");
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
// 字节转换为字符串
String msg = new String(buffer);
String[] userInfo = msg.split(":");
Map<String,String> userMap = new HashMap<>();
userMap.put("username",userInfo[0]);
userMap.put("password",userInfo[1]);
return userMap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
二、SharedPreferences存储
不同于文件的存储方式,SharedPreferences是使用键值对的方式来存储数据的,保存为.xml文件。
也就是说当保存一条数据的时候,需要给这条数据提供一个对应的键,这样在读取数据的时候就可以通过这个键把相应的值取出来。
而且SharedPreferences还支持多种不同的数据类型存储,如果存储的数据类型是整型,那么读取出来的数据也是整型的,存储的数据是一个字符串,读取出来的数据仍然是字符串。
使用SharedPreferences来进行数据持久化要比使用文件方便很多。
存储方法:
1.写入文件步骤
SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。
SharedPreferences sp = getSharedPreferences(“data”,MODE_PRIVATE);//获取
SharedPreferences对象
SharedPreferences.Editor editor = sp.edit(); // 获取编辑器对象
editor.putString(“name”, “张三”); // 存入String类型数据
editor.putInt(“age”, 8); // 存入int类型数据
editor.commit(); // 提交数据
2.读取文件步骤
SharedPreferences sp = getSharedPreferences(“data”,MODE_PRIVATE);
String data= sp.getString(“name”,“”);
3.删除文件中数据
editor.remove(“name”); // 根据key删除数据
editor.clear(); // 删除所有数据
4. 实现存储和读取用户名和密码实例
创建UserInfoSharePre工具类,实现存储数据方法(saveUserInfo)和读取数据方法(getUserInfo)
public class UserInfoSharedPre {
// 用户数据的存储
public static boolean saveUserInfo(String username, String password, Context context) {
// 获取SharedPreferences对象,同时指定文件名称和访问权限
SharedPreferences sp = context.getSharedPreferences("MyData", Context.MODE_PRIVATE);
// 获取获取SharedPreferences的编辑器对象
SharedPreferences.Editor edit = sp.edit();
// 通过编辑器进行数据的存储
edit.putString("Uname",username);
edit.putString("Pwd",password);
edit.commit();
return true;
}
// 读取用户数据
public static Map<String,String> getUserInfo(Context context) {
// 获取SharedPreferences对象,同时指定文件名称和访问权限
SharedPreferences sp = context.getSharedPreferences("MyData", Context.MODE_PRIVATE);
String username = sp.getString("Uname", "");
String password = sp.getString("Pwd","");
Map<String,String> userMap = new HashMap<>();
userMap.put("username",username);
userMap.put("password",password);
return userMap;
}
}
三、SQLite数据库存储
它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。
存储方法:
1. 创建数据库步骤
(一)定义数据库帮助类
SQLiteOpenHelper是SQLiteDatabase的一个帮助类,用来管理数据库的创建和版本的更新
class MyDbHelper extends SQLiteOpenHelper {
// 构造器的作用:(参数:上下文,数据库文件的名称,结果集工厂,版本号)定义数据库
public MyDbHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
// 数据库初始化时创建的表,用于创建表或视图文件
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL("create table user(user_id integer primary key autoincrement,userName varchar(10),password varchar(10))");
}
// 升级方法(当数据库的版本号增加时调用)
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
(二)创建数据库和表
// 设置数据库的相关参数,初始化数据库
MyDbHelper myDbHelper = new MyDbHelper(SQLiteActivity.this,"MyDatabase.db",null,1);
// 通过帮助类获取到数据库对象
SQLiteDatabase db = myDbHelper.getWritableDatabase();
通过数据库对象可以执行如下方法:
1.插入方法insert
// 创建ContentValues对象用于存储记录的字段值(键值对方式:键对应字段名,值对应字段具体的值)
ContentValues contentValues = new ContentValues();
contentValues.put("userName","张三");
contentValues.put("password","123456");
db.insert("user",null,contentValues);
上面等同于
db.execSQL("insert into user(userName,password) values (?,?)",new Object[]{
<!--{C}%3C!%2D%2D%20%2D%2D%3E-->"张三","123456"});
执行完之后
db.close();
2.查询方法query
调用query方法查询数据库中的数据,返回一个行数集合cursor
public Cursor query(
String table, String[] columns,
String selection,
String[] selectionArgs,
String groupBy,
String having,
String orderBy,
String limit
)
各参数说明: table:表名称 colums:列名称数组,返回那些字段,null表示所有字段 selection:查询条件子句,相当于select语句where关键字后面的部分,在条件子句允许使用占位符“?” selectionArgs:对应于selection语句中占位符的值,值在数组中的位置与占位符在语句中的位置必须一致, 否则就会有异常。 groupBy:相当于select语句group by关键字后面的部分 having:相当于select语句having关键字后面的部分 orderBy:排序类 limit:分页查询的限制,指定偏移量和获取的记录数 Cursor:返回值,相当于结果集ResultSet
// Cursor: 结果集,内有游标指向结果集中的某一条记录,初始时指向第一条
Cursor cursor = db.query("user", new String[]{"userName,password"}, null, null, null, null, null, null);
cursor.moveToFirst();
while (cursor.moveToNext()) { // 移动游标指向下一行数据
showInfo.append("\n" + "用户名" + cursor.getString(0) + ",密码" + cursor.getString(1));
}
cursor.close();
db.close();
对于cursor也提供了一些方法如下:
3.删除方法delete
返回删除的记录条数
public boolean deleteData(String deleteId) {
int i = db.delete("user", "id=?", new String[]{deleteId});
return i > 0 ? true : false;
}
4.修改方法update
返回更新的记录条数
ContentValues contentValues = new ContentValues();
contentValues.put("userName","李四");
contentValues.put("password","123123");
int i = db.update("user", contentValues, "id=?", new String[]{updateId});
等同于
db.execSQL("update user set userName=?,password=? where id=?",new Object[]{
<!--{C}%3C!%2D%2D%20%2D%2D%3E-->username1,password1,id});
四、ContentProvider存储
主要功能是与外界共享数据。如果数据通过内容提供商与外界共享,其他应用程序可以从内容提供商处查询数据,并可以更新、删除和添加数据。如果通过文件操作方式与外界共享数据,由于存储方式的不同,数据的访问方式也不会统一,不同存储方式共享文件的ApI也不一样。如果使用内容提供商与外界共享数据,数据的访问方式将会统一。使用统一的API访问共享数据。
存储方法:
1.创建内容提供者需要继承android.content.ContentProvider
2.清单文件中进行配置:
<!–android:name:指定内容提供者的类名,android:authorities:调用内容..名称,随意取 –> <provider android:name=”.PersonProvider” android:authorities=”cn.test.providers.personprovider”/>
ContentProvider类主要方法
public boolean onCreate()
该方法在ContentProvider创建后就会被调用, Android开机后, ContentProvider在其它应用第一次访问它时才会被创建。
public Uriinsert(Uri uri, ContentValues values)
该方法用于供外部应用往ContentProvider添加数据。
public int delete(Uri uri, String selection,String[] selectionArgs)
该方法用于供外部应用从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, Stringselection, String[] selectionArgs)
该方法用于供外部应用更新ContentProvider中的数据。
public Cursorquery(
Uri uri, String[]projection,
String selection, String[] selectionArgs,
String sortOrder
)
该方法用于供外部应用从ContentProvider中获取数据。
示例:
内容提供者类,实现数据的增删改查
public class PersonProvider extends ContentProvider {
//创建工具类实现Uri匹配
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS = 1;
private static final int PERSON = 2;
static{
MATCHER.addURI("cn.test.providers.personprovider", "person", PERSONS);
MATCHER.addURI("cn.test.providers.personprovider", "person/#", PERSON);
}
private DBOpenHelper dbOpenHelper = null;
@Override
public boolean onCreate() {
dbOpenHelper = new DBOpenHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
switch (MATCHER.match(uri)) {
case PERSONS: // 获取person表中的所有数据 /person
return db.query("person", projection, selection, selectionArgs, null, null, sortOrder);
case PERSON: // 获取person表中的指定id的数据 /person/20
long id = ContentUris.parseId(uri);
String where = "personid="+ id;
if(selection!=null && !"".equals(selection.trim())){
where += " and "+ selection;
}
return db.query("person", projection, where, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("Unknown Uri:"+ uri);
}
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
//取得数据库操作实例
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
switch (MATCHER.match(uri)) {
case PERSONS:
//执行添加,返回行号,如果主健字段是自增长的,那么行号会等于主键id
long rowid = db.insert("person", "name", values);
//得到拼好的uri
Uri insertUri = ContentUris.withAppendedId(uri, rowid);
//发出数据变化通知(person表的数据发生变化)
getContext().getContentResolver().notifyChange(uri, null);
return insertUri;
default:
//不能识别uri
throw new IllegalArgumentException("Unknown Uri:"+ uri);
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
//受影响的行数
int num = 0;
switch (MATCHER.match(uri)) {
case PERSONS: // 删除person表中的所有数据 /person
num = db.delete("person", selection, selectionArgs);
break;
case PERSON: // 删除person表中的指定id的数据 /person/20
long id = ContentUris.parseId(uri);
String where = "personid="+ id;
if(selection!=null && !"".equals(selection.trim())){
where += " and "+ selection;
}
num = db.delete("person", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri:"+ uri);
}
return num;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int num = 0;
switch (MATCHER.match(uri)) {
case PERSONS: // 更新person表中的所有数据 /person
num = db.update("person", values, selection, selectionArgs);
break;
case PERSON: // 更新person表中的指定id的数据 /person/20
long id = ContentUris.parseId(uri);
String where = "personid="+ id;
if(selection!=null && !"".equals(selection.trim())){
where += " and "+ selection;
}
num = db.update("person", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri:"+ uri);
}
return num;
}
}
其他工程中访问:
public class AccessContentProiderTest extends AndroidTestCase {
public void testInsert() throws Throwable{
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://cn.test.providers.personprovider/person");
ContentValues values = new ContentValues();
values.put("name", "lili");
values.put("phone", "110");
values.put("amount", "3000000000");
resolver.insert(uri, values);
}
public void testDelete() throws Throwable{
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://cn.test.providers.personprovider/person");
int num =resolver.delete(uri, null, null);
}
public void testUpdate() throws Throwable{
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://cn.test.providers.personprovider/person/65");
ContentValues values = new ContentValues();
values.put("amount", 500);
resolver.update(uri, values, null, null);
}
public void testQuery() throws Throwable{
ContentResolver resolver = getContext().getContentResolver();
Uri uri = Uri.parse("content://cn.test.providers.personprovider/person/65");
Cursor cursor = resolver.query(uri, null, null, null, "personid asc");
while(cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex("name"));
Log.i("AccessContentProviderTest", name);
}
}
}
希望本文所述对大家Android程序设计有所帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/118794.html