android 提供了五种数据存储的方式:
1. SharePreference:采用XML格式将数据存储到设备中,只能在同一包名内使用;
2. 文件存储:存储文件到 /data/data/包名/files 内存里面,默认是私有的访问权限;
3. SQLite数据库:Android自带的轻量级嵌入式数据库,支持SQL语句;
4. ContentProvider:主要用于应用程序之间的数据交换;
5.网络存储:通过网络上的存储空间上传下载数据;
下面具体看一下这五种存储方式(下面源码地址,封装好的工具类,可直接使用):
1. SharePreference(偏好设置)
特点:采用 XML 格式将数据存储到设备中,只能在同一包名内使用;是轻量级的数据存储方式,本质是存储 key-value 键值对;
用途:存储个人数据,比如昵称,年龄,ID等;
实例代码:
首先创建一个名字叫 SPInfoUtils 工具类,里面有存储数据,取出数据,清空偏好设置等方法;代码如下:
/**
* author: wu
* date: on 2018/9/25.
* describe:偏好设置存储信息
*/
public class SPInfoUtils {
//储存大量信息
public static void saveMoreInfo(Context context, HashMap<String, String> map) {
SharedPreferences sharedPreferences = context.getSharedPreferences("SP", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
HashMap.Entry entry = (HashMap.Entry) iterator.next();
editor.putString((String) entry.getKey(), (String) entry.getValue());
}
editor.commit();
}
//存储/改变单个信息
public static void saveLittleInfo(Context context, String key, String value) {
SharedPreferences sharedPreferences = context.getSharedPreferences("SP", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(key, value);
editor.commit();
}
//取出信息
public static String getInfo(Context context, String key) {
SharedPreferences sharedPreferences = context.getSharedPreferences("SP", Context.MODE_PRIVATE);
String value = sharedPreferences.getString(key, "");
return value;
}
//清空存储的数据
public static void cearSP(Context context, String name) {
SharedPreferences sharedPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE);
SharedPreferences.Editor edit = sharedPreferences.edit();
edit.clear();
edit.commit();
}
}
创建完工具类之后,就可以存储,取出数据了;代码如下:
//存入大量信息
HashMap<String, String> map = new HashMap<>();
map.put("name", "张三");
map.put("age", "20");
map.put("like", "吃喝");
SPInfoUtils.saveMoreInfo(MainActivity.this, map);
//改变单个信息
SPInfoUtils.saveLittleInfo(MainActivity.this, "age", "18");
//取出其年龄
SPInfoUtils.getInfo(MainActivity.this,"age");
可以看出,数据中年龄可以取出,为18;SharePreference 的简单使用到此就讲完了。
2. 文件存储
特点:存储文件到 /data/data/包名/files 内存里面,默认是私有的访问权限;可以存放大量的数据;
用途:存储视频,音频等文件;
实例代码(存储 txt 文件到手机中为例):
首先创建一个名字叫 FileSaveUtils 的工具类,里面有存储文件和取出文件内容两个方法:
/**
* author: wu
* date: on 2018/9/25.
* describe:文件存储
*/
public class FileSaveUtils {
//文件存储
public static void saveFile(Context context, String fileName, String fileContent) {
//存储到手机
try {
FileOutputStream outStream = context.openFileOutput(fileName, Context.MODE_WORLD_READABLE);
outStream.write(fileContent.getBytes());
outStream.close();
} catch (FileNotFoundException e) {
return;
} catch (IOException e) {
return;
}
}
//文件读取,返回文件的内容
public static String getFile(Context context, String fileName) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
FileInputStream inStream = context.openFileInput(fileName);
byte[] buffer = new byte[1024];
int length;
while ((length = inStream.read(buffer)) != -1) {
stream.write(buffer, 0, length);
}
stream.close();
inStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return stream.toString();
}
}
注释:openFileOutput()方法的第二参数用于指定操作模式,有四种模式,分别为:
Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容;
Context.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件;
Context.MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;
Context.MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入;
工具类写好之后,就可以存储文件了:
//文件存储
FileSaveUtils.saveFile(MainActivity.this,"a.txt","这是文件存储");
//取出存储的文件,文本信息
String str = FileSaveUtils.getFile(MainActivity.this,"a.txt");
文件存储的简单使用到此就讲完了。
3.SQLite数据库
特点:Android 自带的轻量级嵌入式数据库,支持SQL语句;利用很少的内存就有很好的性能,任何开发人员都可以使用它;
用途:存储拥有共同特征的表结构,比如淘宝购物车,美团购物车等;
实例代码:
先创建一个名字 SQliteSaveUtils 的类,里面有增删改查方法:
/**
* author: wu
* date: on 2018/9/25.
* describe:数据库存储信息
*/
public class SQliteSaveUtils {
private DBHelper dbHelper;
public SQliteSaveUtils(Context context) {
dbHelper = new DBHelper(context, "users.db", null, 1);
}
//创建数据库名称为user,里面有标题,价钱,颜色,数量,大小,id等;
class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table user("
+ "title text not null,"
+ "money text not null,"
+ "color text not null,"
+ "number text not null,"
+ "size text not null,"
+ "goods_id text not null,"
+ "size_id text not null)";
db.execSQL(sql);
Log.i("TAG", "table create ok");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i("TAG", "onUpgrade");
String sql = "DROP TABLE contact";
db.execSQL(sql);
onCreate(db);
}
}
//插入数据
public long insert(String table, ContentValues values) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
long id = db.insert(table, null, values);
Log.i("TAG", "insert ok!");
db.close();
return id;
}
//查询数据
public Cursor query(String sql, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
return db.rawQuery(sql, selectionArgs);
}
//更新数据
public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rows = db.update(table, values, whereClause, whereArgs);
db.close();
return rows;
}
//删除数据,whereClause为删除条件
public int delete(String table, String whereClause, String[] whereArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rows = db.delete(table, whereClause, whereArgs);
db.close();
return rows;
}
}
创建完数据库的工具类之后,就可以使用了:
/**
*新建数据库
*/
SQliteSaveUtils sqliteSave = new SQliteSaveUtils(MainActivity.this);
/**
*删除数据
*/
sqliteSave.delete("user", "", null);
/**
*插入两组数据
*/
ContentValues values = new ContentValues();
values.put("title", "大衣");
values.put("money", "249");
values.put("color", "卡其色");
values.put("number", "1");
values.put("size", "XL");
values.put("goods_id", "898");
values.put("size_id", "11");
sqliteSave.insert("user", values);
values.put("title", "短裤11111111111111");
values.put("money", "249111111111111");
values.put("color", "卡其色11111111111");
values.put("number", "1111111111111");
values.put("size", "XL11111111111");
values.put("goods_id", "89811111111111");
values.put("size_id", "111111111111");
long id = sqliteSave.insert("user", values);
if (id == -1) {
Log.e("=====数据库插入", "失败");
return;
}
Log.e("=====数据库插入", "ok,id=" + id);
/**
*更新数据(将大衣的价格修改为一万)
*/
ContentValues values1 = new ContentValues();
values1.put("money","一万");
Log.e("=====更新数据1更新成功", sqliteSave.update("user",values1,"title= ?",new String[]{"大衣"})+"");
/**
*查询数据(查询所有数据)
*/
String sql = "SELECT * FROM user ";
Cursor cursor2 = sqliteSave.query(sql, null);
if(cursor2.moveToFirst()){
do{
Log.e("=====数据库title", cursor2.getString(cursor2.getColumnIndex("title")));
Log.e("=====数据库money", cursor2.getString(cursor2.getColumnIndex("money")));
Log.e("=====数据库color", cursor2.getString(cursor2.getColumnIndex("color")));
Log.e("=====数据库number", cursor2.getString(cursor2.getColumnIndex("number")));
Log.e("=====数据库size", cursor2.getString(cursor2.getColumnIndex("size")));
Log.e("=====数据库goods_id", cursor2.getString(cursor2.getColumnIndex("goods_id")));
Log.e("=====数据库size_id", cursor2.getString(cursor2.getColumnIndex("size_id")));
}while(cursor2.moveToNext());
}
写完之后来看 Log 日志:
可以看出,数据库插入成功,大衣的价格更新为一万,并且可以取出两组数据;SQLite 数据库存储到此就讲完了。
4.ContentProvider
特点:主要用于应用程序之间的数据交换;可以读取程序的数据,也可以删除程序的数据;
用途:获取联系人信息;
实例代码:
首先在 AndroidManifest.xml 文件中添加读取联系人权限:
<!-- 读取联系人权限 -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
然后再代码中加入:
//得到ContentResolver对象
ContentResolver cr = getContentResolver();
//取得电话本中开始一项的光标
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
//向下移动光标
while(cursor.moveToNext()) {
//取得联系人名字
int nameFieldColumnIndex = cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME);
String contact = cursor.getString(nameFieldColumnIndex);
Log.e("=====姓名", contact+"");
//取得电话号码
String ContactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Cursor phone = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + ContactId, null, null);
while(phone.moveToNext())
{
String PhoneNumber = phone.getString(phone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
//格式化手机号
PhoneNumber = PhoneNumber.replace("-","");
PhoneNumber = PhoneNumber.replace(" ","");
Log.e("=====手机号", PhoneNumber+"");
}
}
添加完毕后,运行可以看到 Log 打印日志已经取出来联系人和手机号:
ContentProvider 到此讲解完了。
5.网络存储
特点:通过网络上的存储空间上传下载数据;
用途:网络请求;
不再讲了。