App要是不支持离线查看数据内容,大概会造成极差的用户体验吧
持久化技术
简介
Android内置的实现持久化功能的方式如下
- 文件存储
- SharePreference
- 数据库存储
- SD卡(与文件存储类似,需要权限)
文件存储
数据一般会被存储到/data/data/<package name>/files/目录之下
存数据
public static void save(String str, Context context) {
String data = str;
FileOutputStream out = null;
BufferedWriter writer = null;
try {
//这里的save就是files目录下的文件名
out = context.openFileOutput("save", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(str);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
assert out != null;
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
布局如图
布局
在Edittext中输入Hello Stars
点击Save,即完成保存操作
-
点击菜单栏中的View->Device File Explorer
Device File Explorer -
找到目录/data/data/<package name>/files/
目录
5.双击save文件,就能看到数据啦
数据
取出数据
过程大同小异,取出数据后就可以在TextView中显示啦
public static String read(Context context) {
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder stringBuilder = new StringBuilder();
String data = "";
try {
in = context.openFileInput("save");
reader = new BufferedReader(new InputStreamReader(in));
while ((data = reader.readLine()) != null) {
stringBuilder.append(data);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return stringBuilder.toString();
}
效果图
效果图
SharePreference存储
与文件存储相比,代码量少很多,同理也是打开Device File Explorer,目录由files变为shared_prefs即可查看了
image.png
public static void writeInSp(Context context, String value) {
SharedPreferences.Editor editor = context.getSharedPreferences("save", Context.MODE_PRIVATE).edit();
editor.putString("key", value);
editor.apply();
}
public static String readFromSp(Context context) {
SharedPreferences sp = context.getSharedPreferences("save", Context.MODE_PRIVATE);
return sp.getString("key", "defValue");
}
SQLite存储
SQLite是一款比较轻量的数据库,运算速度快,占用内存少
建表
public class DbHelper extends SQLiteOpenHelper {
private Context context;
public DbHelper(Context context) {
//List是数据库的名字
super(context, "List.db", null, 1);
this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
//这里为List数据库建立了一张Student的表,数据库可以有多张表
String sql = "create table Student (id integer primary key autoincrement, name text, number integer)";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//此处对表进行更新,可以对表进行增删改操作
}
}
布局如图,这里我已经插入了数据
布局.png
增
- 写入姓名填入:hhh,写入学号填入:666
//Button 增的点击事件中
ContentValues cv = getContentValues();
db.insert("Student", null, cv);
//填入CV
@NonNull
private ContentValues getContentValues() {
String name = etName.getText().toString();
String number = etNumber.getText().toString();
ContentValues cv = new ContentValues();
if (!name.isEmpty() && !number.isEmpty()) {
cv.put("name", name);
cv.put("number", number);
}
return cv;
}
image.png
删
这里是通过学号删除,写入学号填入:1
//onClick事件监听器中的代码
String number = etNumber.getText().toString();
if (!number.isEmpty())
//"number = ?", new String[]{number} 这里就是查询条件,即number = number(etNumber中的数据),也可以将 = 换成 > 或 <
db.delete("Student", "number = ?", new String[]{number});
image.png
改
这里是根据名字改学号
String name = etName.getText().toString();
if (!name.isEmpty())
db.update("Student", getContentValues(), "name = ?", new String[]{name});
将libai的学号改为1
image.png
查
这里是查询表中的所有数据,表名为Student,无约束条件
StringBuilder stringBuilder = new StringBuilder();
Cursor cursor = db.query("Student", null, null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
String n = cursor.getString(cursor.getColumnIndex("name"));
String b = cursor.getString(cursor.getColumnIndex("number"));
stringBuilder.append("姓名:" + n + ",学号:" + b + "\n");
} while (cursor.moveToNext());
}
tvStudent.setText("学生数据:\n" + stringBuilder.toString());
cursor.close();
Tips
- MODE_PRIVATE:这是上文中我们使用文件存储,SP存储用到的模式,该模式下,只能允许调用应用程序访问,其他的无权限
- 现在Github中有各种各样的数据库框架,如Litepal,Jetpack组建中的Room,GreenDao等,各有优势,虽不能一一学习,但可以查看介绍,挑着来学