一,sp存储
SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstanceState保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整形、Int整形、String字符串型的保存。
它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。
其存储位置在/data/data/<包名>/shared_prefs目录下。
SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。
SharedPreferences: 对应sp文件的接口
context. getSharedPreferences (String name, int mode): 得到SP对象
name: 文件名(不带.xml)
mode: 生成的文件模式(是否是私有的,即其它应用是否可以访问)
Editor sp.edit() : 得到Editor对象
Xxx sp.getXxx(name,defaultValue): 根据name得到对应的数据
Editor : 能更新sp文件的接口
Editor put(name, value) : 保存一个键值对, 没有真正保存到文件中
Editor remove(name)
commit(): 提交, 数据真正保存到文件中了
public void save(View v) {
//2.得到Editor对象
Editor edit=sp.edit();
//3.得到输入的key/value
String key = et_sp_key.getText().toString();
String value = et_sp_value.getText().toString();
//4.使用Editor保存key-value
edit.putString(key, value).commit();
//5.提示
Toast.makeText(this, "保存完成", 0).show();
}
2.sp存储的读取数据
public void read(View v) {
//1.得到输入的key
String key = et_sp_key.getText().toString();
//2.根据key读取对应的value
String value = sp.getString(key, null);
//3.显示
if(value==null){
Toast.makeText(this, "没有找到对应的value", 0).show();
}else{
et_sp_value.setText(value);
}
}
二,手机内部文件存储
应用运行需要的一些较大的数据或图片可以用文件保存的手机内部
文件类型: 任意
数据保存的路径: /data/data/projectPackage/files/
可以设置数据只能是当前应用读取, 而别的应用不可以
应用卸载时会删除此数据
读取文件:FileInputStream fis = openFileInput("logo.png");
保存文件:FileOutputStream fos = openFileOutput("logo.png", MODE_PRIVATE)
得到files文件夹对象:File filesDir = getFilesDir();
操作asserts下的文件
得到AssetManager : context.getAssets();
读取文件: InputStream open(filename);
加载图片文件:Bitmap BitmapFactory.decodeFile(String pathName) // .bmp/.png/.jpg
1.保存数据:
public void save(View v) throws IOException {
//1.得到InputStream-->读取assets下的logo.png
//得到AssetManager
AssetManager manager = getAssets();
//读取文件
InputStream is = manager.open("logo.png");
//2.得到OutputStream-->/data/data/packageName/files/logo.png
FileOutputStream fos = openFileOutput("logo.png", Context.MODE_PRIVATE);
//3.边读边写
byte[] buffer=new byte[1024];
int len = -1;
while((len = is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
fos.close();
is.close();
//4.显示
Toast.makeText(this, "保存完成", 0).show();
}
2.读取数据
public void read(View v) {// /data/data/packageName/files/logo.png
//1.得到图片文件路径
///data/data/packageName/files
String filesPath = getFilesDir().getAbsolutePath();
String imagePath = filesPath + "/logo.png";
//2.读取加载图片文件得到bitmap对象
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
//3.将其设置到imgeView中显示
iv_if.setImageBitmap(bitmap);
}
三, SD卡外部file存储
应用运行用到的数据文件(如图片)可以保存到sd卡中
文件类型: 任意
数据保存的路径:
路径1: /storage/sdcard/Android/data/packageName/files/
路径2: /storage/sdcard/xxx/
路径1 :其它应用可以访问,应用卸载时删除
路径2 : 其它应用可以访问, 应用卸载时不会删除
必须保证sd卡挂载在手机上才能读写, 否则不能操作
Environment : 操作SD卡的工具类
得到SD卡的状态:Environment.getExternalStorageState()
得到SD卡的路径:Environment.getExternalStorageDirectory()
SD卡可读写的挂载状态值:Environment.MEDIA_MOUNTED
context. getExternalFilesDir(): 得到/mnt/sdcard/Android/data/pageckage_name/files/xxx.txt
操作SD卡的权限: android.permission.WRITE_EXTERNAL_STORAGE
路径1:
1.保存数据
public void save(View v) throws IOException {
//1.判断sd卡状态,如果是挂载的状态才继续,否则提示
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//2.读取输入的文件名\内容;
String fileName = et_of_name.getText().toString();
String content = et_of_content.getText().toString();
//3.得到指定文件的OutputStream
//1).得到sd卡下的files路径
String filesPath = getExternalFilesDir(null).getAbsolutePath();
//2).组成完整路径
String filePath = filesPath + "/" + fileName;
//3).创建FileOutputStream
FileOutputStream fos = new FileOutputStream(filePath);
//4.写数据
fos.write(content.getBytes("utf-8"));
fos.close();
//5.提示
Toast.makeText(this, "保存完成", 0).show();
}else{
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
2.读取数据
public void read(View v) throws IOException {
//1.判断sd卡状态,如果是挂载的状态才继续,否则提示
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//2.读取输入的文件名\内容;
String fileName = et_of_name.getText().toString();
//3.得到指定文件的OutputStream
//1).得到sd卡下的files路径
String filesPath = getExternalFilesDir(null).getAbsolutePath();
//2).组成完整路径
String filePath = filesPath + "/" + fileName;
//3).创建FileInputStream
FileInputStream fis = new FileInputStream(filePath);
//4.写数据
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while((len=fis.read(buffer))!=-1){
baos.write(buffer,0,len);
}
String content = baos.toString();
//5.显示
et_of_content.setText(content);
}else{
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
路径2:
1.保存数据
// /storage/sdcard/atguigu/xxx.txt
public void save2(View v) throws Exception {
//1.判断sd卡状态,如果是挂载的状态才继续,否则提示
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//2.读取输入的文件名\内容;
String fileName = et_of_name.getText().toString();
String content = et_of_content.getText().toString();
//3.得到指定文件的OutputStream
//1)./storage/sdcard/
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
//2)./storage/sdcard/atguigu/(创建文件夹)
File file = new File(sdPath+"/atguigu");
if(!file.exists()){
file.mkdirs();//创建文件夹
}
//3)./storage/sdcard/atguigu/xxx.txt
String filePath = sdPath+"/atguigu/"+fileName;
//4).创建输出流
FileOutputStream fos = new FileOutputStream(filePath);
//4.写数据
fos.write(content.getBytes("utf-8"));
fos.close();
//5.提示
Toast.makeText(this, "保存完成", 0).show();
}else{
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
2.读取数据
public void read2(View v) throws Exception {
//1.判断sd卡状态,如果是挂载的状态才继续,否则提示
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//2.读取输入的文件名\内容;
String fileName = et_of_name.getText().toString();
//3.得到指定文件的IntputStream
//1)./storage/sdcard/
String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String filePath=sdPath+"/atguigu/"+fileName;
//3).创建FileInputStream
FileInputStream fis = new FileInputStream(filePath);
//4.读取数据,成String
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = -1;
while((len=fis.read(buffer))!=-1){
baos.write(buffer,0,len);
}
String content = baos.toString();
fis.close();
//5.显示
et_of_content.setText(content);
}else{
Toast.makeText(this, "sd卡没有挂载", 0).show();
}
}
四,SQLite数据库存储
1)说明
应用运行需要保存一系列有一定结构的数据, 比如说公司员工信息
文件类型: .db
数据保存的路径: /data/data/projectPackage/databases/xxx.db
默认情况下其它应用不能访问, 当前应用可以通过ContentProvider提供其它应用操作
应用卸载时会删除此数据
SQLite (http://www.sqlite.org/),是一款轻型的关系型数据库服务器, 移动设备的数据库存储都使用SQLite,
2)它的特点:
安装文件小: 最小只有几百K, Android系统已经安装
支持多操作系统: Android, WP, IOS, Windows, Linux等
支持多语言: 比如 Java 、 PHP、C#等.
处理速度快: 处理速度比Mysql, Oracle, SqlServer都要快(数据量不是特别大)
Sqlite中的一个数据库就是一个.db文件(本质上.db的后缀都可以不指定)
3)Sqlite数据库命令行
adb shell 进入系统根目录
cd data/data/…/databases : 进入包含数据库文件的文件夹下
sqlite3 contacts2.db : 使用sqlite3命令连接指定的数据库文件, 进入连接模式
.help : 查看命令列表
.tables : 查看所有表的列表
执行insert/delete/update/select语句
.exit : 退出数据库连接模式
Ctrl + C : 直接退出sell模式
4)SQLite支持的数据类型
INT/INTEGER : 整数
FLOAT/DOUBLE : 小数
CHAR/VARCHAR/TEXT : 字符串文本
BLOB : 文件
DATE/ DATETIME : 日期/日期时间
5)Sqlite的CRUD语句
/*插入*/
INSERT INTO employee (name,salary,birthday) VALUES('Tom', 8000, '1988-09-21');
/*删除*/
DELETE FROM employee WHERE _id=2
/*更新*/
UPDATE employee SET name='Jack',salary=salary+1000 WHERE _id=1
/*查找*/
SELECT * FROM employee where _id=3
6)SQLiteOpenHelper: 数据库操作的抽象帮助类
SQLiteOpenHelper(Context context, String name,
CursorFactory factory, int version) : 构造方法, 指定数据库文件名和版本号
abstract void onCreate(SQLiteDatabase db) : 用于创建表
abstract void onUpgrade() : 用于版本更新
SqliteDatabase getReadableDatabase() : 得到数据库连接
7)SqliteDatabase: 代表与数据库的连接的类
long insert(): 用于执行insert SQL, 返回id值
int update(): 用于执行update SQL
int delete(): 用于执行delete SQL
Cursor query(): 用于执行select SQL, 返回包含查询结果数据的Cursor
void execSql(sql) : 执行sql语句
beginTransaction(): 开启事务
setTransactionSuccessful(): 设置事务是成功的
endTransaction(): 结束事务, 可能提交事务或回滚事务
openDatabase(String path, CursorFactory factory, int flags): 得到数据库连接
8)Cursor : 包含所有查询结果记录的结果集对象(光标,游标)
int getCount() : 匹配的总记录数
boolean moveToNext() : 将游标移动到下一条记录的前面
Xxx getXxx(columnIndex) : 根据字段下标得到对应值
int getColumnIndex(columnname): 根据字段名得到对应的下标
数据库操作的帮助类
package com.example.activitydemo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* 数据库操作的帮助类
* @author Xiaocici
*
*/
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context,int version) {
super(context,"atguigu",null, version);
// TODO Auto-generated constructor stub
}
/**
* 什么时候才会创建数据库文件?
* 1)数据库文件不存在
* 2)
*
* 当数据库文件创建的时候调用
* 建表
* 插入一些初始化数据
*/
@Override
public void onCreate(SQLiteDatabase db) {
Log.e("TAG", "DBHelper create");
//建表
String sql = "create table person( _id integer primary key autoincrement, name varchar,age int)";
db.execSQL(sql);
//插入一些初始化数据
db.execSQL("insert into person(name,age) values( 'Tom1',11)");
db.execSQL("insert into person(name,age) values( 'Tom2',12)");
db.execSQL("insert into person(name,age) values( 'Tom3',13)");
}
//当传入的版本号大于数据库的版本号时调用
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.e("TAG", "DBHelper onUpgrade");
}
}
创建库
public void testCreateDB(View v){
DBHelper dbHelper = new DBHelper(this, 1);
//获取连接
SQLiteDatabase database = dbHelper.getReadableDatabase();
Toast.makeText(this, "创建数据库", 0).show();
}
更新库
public void testUpdateDB(View v){
DBHelper dbHelper = new DBHelper(this, 2);
//获取连接
SQLiteDatabase database = dbHelper.getReadableDatabase();
Toast.makeText(this, "更新数据库", 0).show();
}
添加记录
public void testInsert(View v){
//1.得到连接
DBHelper dbHelper = new DBHelper(this, 2);
SQLiteDatabase database = dbHelper.getReadableDatabase();
//2.执行insert insert into person(name,age) values('Tom',12)
ContentValues values = new ContentValues();
values.put("name", "Tom");
values.put("age", 12);
long id = database.insert("person", null, values);
//3.关闭
database.close();
//4.提示
Toast.makeText(this, "id=" + id, 0).show();
}
更新
public void testUpdate(View v){
DBHelper dbHelper = new DBHelper(this, 2);
SQLiteDatabase database = dbHelper.getReadableDatabase();
//执行Update update person set name=Jack,age=13 where _id=4
ContentValues values = new ContentValues();
values.put("name", "Jack");
values.put("age", 13);
int updateCount = database.update("person", values , "_id=?", new String[]{"4"});
database.close();
Toast.makeText(this, "updateCount=" + updateCount, 0).show();
}
删除
public void testDelete(View v){
//1.得到连接
DBHelper dbHelper = new DBHelper(this, 2);
SQLiteDatabase database = dbHelper.getReadableDatabase();
//2.执行delete delete from person where _id=2
int deleteCount = database.delete("person", "_id=2", null);
//3.关闭
database.close();
//4.提示
Toast.makeText(this, "deleteCount=" + deleteCount, 0).show();
}
查询
public void testQuery(View v){
//1.得到连接
DBHelper dbHelper = new DBHelper(this, 2);
SQLiteDatabase database = dbHelper.getReadableDatabase();
//2.执行query select * from person
Cursor cursor = database.query("person", null, null, null, null, null, null);
//Cursor cursor = database.query("person", null, "_id=?", new String[]{"3"}, null, null, null);
//得到总匹配数
int count = cursor.getCount();
//取出cursor中的所有数据
while(cursor.moveToNext()){
//_id
int id = cursor.getInt(0);
//name
String name = cursor.getString(1);
//age
int age = cursor.getInt(cursor.getColumnIndex("age"));
Log.e("TAG", id+"-" + name + "-" + age);
}
//3.关闭
cursor.close();
database.close();
//4.提示
Toast.makeText(this, "count=" + count, 0).show();
}
/*
*测试事务处理
*update person set age=15 where _id=1
*update person set age=17 where _id=3
*
*一个功能中对数据库进行的多个操作,要么都成功,要么都失败
*事务处理的3步:
*1.开启事务(获取连接后)
*2.设置事务成功(在全部正常执行完后)
*3.结束事务(finally)
*/
public void testTransaction(View v) {
SQLiteDatabase database = null;
try{
// 得到连接
DBHelper dbHelper = new DBHelper(this, 2);
database = dbHelper.getReadableDatabase();
//1.开启事务(获取连接后)
database.beginTransaction();
// 执行update update person set age=15 where _id=1
ContentValues values = new ContentValues();
values.put("age", 15);
int updateCount = database.update("person", values , "_id=?", new String[]{"1"});
Log.e("Tag","updateCount="+ updateCount);
//出了异常
boolean flag=true;
if(flag){
throw new RuntimeException("出异常啦!!!");
}
// 执行update update person set age=17 where _id=3
values = new ContentValues();
values.put("age", 17);
int updateCount2 = database.update("person", values , "_id=?", new String[]{"3"});
Log.e("Tag", "updateCount2=" + updateCount2);
//2.设置事务成功(在全部正常执行完后)
database.setTransactionSuccessful();
//关閉
database.close();
}catch(Exception e){
e.printStackTrace();
Toast.makeText(this, "出异常了~~", 0).show();
}finally{
//3.结束事务(finally)
if(database==null){
database.endTransaction();
database.close();
}
}
}
五.远程服务器存储
太长了,接下一篇