完成应用Data区数据备份测试。

This commit is contained in:
2026-01-31 19:47:12 +08:00
parent 1db94b52e6
commit 3f924b004c
4 changed files with 180 additions and 5 deletions

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sat Jan 31 10:50:44 GMT 2026 #Sat Jan 31 11:44:12 GMT 2026
stageCount=12 stageCount=12
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.15 baseVersion=15.15
publishVersion=15.15.11 publishVersion=15.15.11
buildCount=20 buildCount=26
baseBetaVersion=15.15.12 baseBetaVersion=15.15.12

View File

@@ -17,6 +17,9 @@ import cc.winboll.studio.libappbase.activities.FTPBackupsActivity;
import cc.winboll.studio.libappbase.dialogs.SFTPBackupsSettingsDialog; import cc.winboll.studio.libappbase.dialogs.SFTPBackupsSettingsDialog;
import cc.winboll.studio.libappbase.models.SFTPAuthModel; import cc.winboll.studio.libappbase.models.SFTPAuthModel;
import java.util.HashMap; import java.util.HashMap;
import android.os.Environment;
import java.io.File;
import cc.winboll.studio.appbase.model.TestBean;
/** /**
* @Author ZhanGSKen<zhangsken@qq.com> * @Author ZhanGSKen<zhangsken@qq.com>
@@ -40,14 +43,26 @@ public class MainActivity extends Activity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
ToastUtils.show("onCreate"); // 显示 Activity 创建提示(调试用) //ToastUtils.show("onCreate"); // 显示 Activity 创建提示(调试用)
setContentView(R.layout.activity_main); // 加载主界面布局 setContentView(R.layout.activity_main); // 加载主界面布局
// 初始化 Toolbar 并设置为 ActionBar // 初始化 Toolbar 并设置为 ActionBar
mToolbar = findViewById(R.id.toolbar); mToolbar = findViewById(R.id.toolbar);
setActionBar(mToolbar); // 将 Toolbar 替代系统默认 ActionBar setActionBar(mToolbar); // 将 Toolbar 替代系统默认 ActionBar
initTestData();
} }
void initTestData() {
TestBean bean = new TestBean();
bean.setTestNum1(456);
TestBean.saveBeanToFile(getFilesDir().getAbsolutePath() + getDataFilesTestBeanPath(), bean);
}
String getDataFilesTestBeanPath() {
return "/BaseBaen/"+TestBean.class.getName()+".json";
}
/** /**
* 创建菜单时回调(加载工具栏菜单) * 创建菜单时回调(加载工具栏菜单)
* 初始化 ActionBar 菜单,加载自定义菜单布局 * 初始化 ActionBar 菜单,加载自定义菜单布局
@@ -154,6 +169,11 @@ public class MainActivity extends Activity {
if (authModel == null) { if (authModel == null) {
dlg.show(); dlg.show();
} else { } else {
// 1. 构建应用Data目录待备份文件Map
HashMap<String, String> dataFileMap = new HashMap<>();
// 存入文件key=唯一标识value=应用外部文件目录下的相对路径与原addSdcardFile参数一致
dataFileMap.put(TestBean.class.getName() + ".json",
getDataFilesTestBeanPath());
// 1. 构建SDCard目录待备份文件Map与BackupUtils的SdcardMap泛型一致String-String // 1. 构建SDCard目录待备份文件Map与BackupUtils的SdcardMap泛型一致String-String
HashMap<String, String> sdcardFileMap = new HashMap<>(); HashMap<String, String> sdcardFileMap = new HashMap<>();
// 存入文件key=唯一标识value=应用外部文件目录下的相对路径与原addSdcardFile参数一致 // 存入文件key=唯一标识value=应用外部文件目录下的相对路径与原addSdcardFile参数一致
@@ -163,6 +183,7 @@ public class MainActivity extends Activity {
// 2. 构建Intent指定跳转到FTPBackupsActivity // 2. 构建Intent指定跳转到FTPBackupsActivity
Intent ftpBackupsIntent = new Intent(getApplicationContext(), FTPBackupsActivity.class); Intent ftpBackupsIntent = new Intent(getApplicationContext(), FTPBackupsActivity.class);
// 3. 序列化传递Map参数使用FTPBackupsActivity中定义的常量避免硬编码 // 3. 序列化传递Map参数使用FTPBackupsActivity中定义的常量避免硬编码
ftpBackupsIntent.putExtra(FTPBackupsActivity.EXTRA_DATA_DIR_FILE_MAP, dataFileMap);
ftpBackupsIntent.putExtra(FTPBackupsActivity.EXTRA_SDCARD_DIR_FILE_MAP, sdcardFileMap); ftpBackupsIntent.putExtra(FTPBackupsActivity.EXTRA_SDCARD_DIR_FILE_MAP, sdcardFileMap);
// 若需要传Data目录的Map同理ftpBackupsIntent.putExtra(FTPBackupsActivity.EXTRA_DATA_DIR_FILE_MAP, dataFileMap); // 若需要传Data目录的Map同理ftpBackupsIntent.putExtra(FTPBackupsActivity.EXTRA_DATA_DIR_FILE_MAP, dataFileMap);

View File

@@ -0,0 +1,154 @@
package cc.winboll.studio.appbase.model;
import android.util.JsonReader;
import android.util.JsonWriter;
import cc.winboll.studio.libappbase.BaseBean;
import cc.winboll.studio.libappbase.LogUtils;
import java.io.IOException;
/**
* 测试实体类
* 继承BaseBean实现JSON序列化/反序列化能力提供基础int类型属性的封装与数据持久化支持
* 适配Java7语法遵循BaseBean统一的反射识别、JSON读写规范
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
* @Date 2026/01/31 19:16:00
* @LastEditTime 2026/02/01 10:46:00
*/
public class TestBean extends BaseBean {
// ====================================== 常量定义 ======================================
/** 当前类的日志 TAG用于调试输出 */
public static final String TAG = "TestBean";
// ====================================== 成员属性 ======================================
/**
* 测试数字属性默认值123
* 基础int类型属性用于测试BaseBean的JSON序列化/反序列化能力
*/
private int testNum1;
// ====================================== 构造方法 ======================================
/**
* 无参构造器(默认初始化)
* 给testNum1赋值默认值123满足反射实例化、JSON解析的无参构造要求
*/
public TestBean() {
this.testNum1 = 123;
LogUtils.d(TAG, "TestBean无参构造器调用testNum1默认初始化值" + this.testNum1);
}
/**
* 有参构造器(自定义初始化)
* @param testNum1 测试数字初始值
*/
public TestBean(int testNum1) {
this.testNum1 = testNum1;
LogUtils.d(TAG, "TestBean有参构造器调用传入testNum1" + testNum1);
}
// ====================================== Get/Set 方法 ======================================
/**
* 设置测试数字属性值
* @param testNum1 待设置的int类型值
*/
public void setTestNum1(int testNum1) {
LogUtils.d(TAG, "setTestNum1调用传入参数" + testNum1);
this.testNum1 = testNum1;
}
/**
* 获取测试数字属性值
* @return 当前testNum1的int类型值
*/
public int getTestNum1() {
LogUtils.d(TAG, "getTestNum1调用返回值" + this.testNum1);
return testNum1;
}
// ====================================== 重写父类BaseBean方法 ======================================
/**
* 重写父类方法:获取当前类的全限定名
* 用于BaseBean反射识别、类名匹配等统一逻辑
* @return 类全限定名cc.winboll.studio.appbase.model.TestBean
*/
@Override
public String getName() {
LogUtils.d(TAG, "getName方法调用返回类全限定名" + TestBean.class.getName());
return TestBean.class.getName();
}
/**
* 重写父类方法将当前对象序列化为JSON持久化存储专用
* 遵循BaseBean规范先执行父类序列化逻辑再处理子类专属字段
* @param jsonWriter JSON写入器外部传入的JSON流操作实例
* @throws IOException JSON写入异常流关闭、格式错误等
*/
@Override
public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException {
LogUtils.d(TAG, "writeThisToJsonWriter调用传入参数JsonWriter" + jsonWriter);
// 执行父类公共字段的序列化逻辑
super.writeThisToJsonWriter(jsonWriter);
// 序列化子类专属字段testNum1
jsonWriter.name("testNum1").value(this.getTestNum1());
LogUtils.d(TAG, "writeThisToJsonWriter执行完成已序列化testNum1" + this.getTestNum1());
}
/**
* 重写父类方法从JSON字段初始化当前对象属性解析JSON专用
* 先让父类处理公共字段再匹配子类专属字段不匹配则返回false跳过
* @param jsonReader JSON读取器外部传入的JSON流操作实例
* @param name 当前解析的JSON字段名
* @return true-字段解析成功false-字段不匹配,需跳过/父类处理
* @throws IOException JSON读取异常字段类型不匹配、流中断等
*/
@Override
public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException {
LogUtils.d(TAG, "initObjectsFromJsonReader调用传入参数name=" + name + "JsonReader=" + jsonReader);
// 父类优先处理公共字段,处理成功则直接返回
if (super.initObjectsFromJsonReader(jsonReader, name)) {
LogUtils.d(TAG, "initObjectsFromJsonReader字段" + name + "由父类BaseBean处理成功");
return true;
}
// 解析子类专属字段
if ("testNum1".equals(name)) {
this.setTestNum1(jsonReader.nextInt());
LogUtils.d(TAG, "initObjectsFromJsonReader解析testNum1成功值为" + this.getTestNum1());
} else {
LogUtils.w(TAG, "initObjectsFromJsonReader字段" + name + "不匹配返回false跳过解析");
// 字段不匹配返回false表示跳过
return false;
}
return true;
}
/**
* 重写父类方法从JSON读取器完整解析并初始化当前对象JSON解析入口
* 负责JSON对象的开始/结束标识处理,遍历所有字段并调用字段解析方法
* 严格遵循writeThisToJsonWriter的序列化结构保证解析一致性
* @param jsonReader JSON读取器外部传入的JSON流操作实例
* @return 解析后的当前TestBean实例支持链式调用
* @throws IOException JSON解析异常格式错误、字段缺失、流异常等
*/
@Override
public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException {
LogUtils.d(TAG, "readBeanFromJsonReader调用传入参数JsonReader" + jsonReader);
// 开始解析JSON对象与序列化结构保持一致
jsonReader.beginObject();
// 遍历所有JSON字段
while (jsonReader.hasNext()) {
String fieldName = jsonReader.nextName();
LogUtils.d(TAG, "readBeanFromJsonReader开始解析字段fieldName=" + fieldName);
// 解析字段,不匹配则跳过该值
if (!this.initObjectsFromJsonReader(jsonReader, fieldName)) {
jsonReader.skipValue();
LogUtils.w(TAG, "readBeanFromJsonReader字段" + fieldName + "解析失败,已跳过该值");
}
}
// 结束JSON对象解析必须调用避免流异常
jsonReader.endObject();
LogUtils.d(TAG, "readBeanFromJsonReader执行完成JSON解析结束当前TestBean实例testNum1" + this.getTestNum1());
// 返回当前实例,支持链式调用
return this;
}
}

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle #Created by .winboll/winboll_app_build.gradle
#Sat Jan 31 10:50:44 GMT 2026 #Sat Jan 31 11:44:12 GMT 2026
stageCount=12 stageCount=12
libraryProject=libappbase libraryProject=libappbase
baseVersion=15.15 baseVersion=15.15
publishVersion=15.15.11 publishVersion=15.15.11
buildCount=20 buildCount=26
baseBetaVersion=15.15.12 baseBetaVersion=15.15.12