diff --git a/.gitignore b/.gitignore index bcc1909..3be31ff 100644 --- a/.gitignore +++ b/.gitignore @@ -97,10 +97,5 @@ lint-results.html ## WinBoLL 基础应用(避免上传敏感配置) /winboll.properties /local.properties - -## WinBoLL 衍生应用, -## 外派类型类库应用需要注释掉以下部分,以便部署通用类库编译配置。 -## APPBase,AES需要上传以下两种配置。 -## OriginMaster 仓库合并各类分支需要忽略的文件修改 /settings.gradle -/gradle.properties +/gradle.properties \ No newline at end of file diff --git a/.winboll/winboll_app_build.gradle b/.winboll/winboll_app_build.gradle index 3522fd3..57b6ba7 100644 --- a/.winboll/winboll_app_build.gradle +++ b/.winboll/winboll_app_build.gradle @@ -66,8 +66,8 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_11 - targetCompatibility JavaVersion.VERSION_11 + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 } // 应用包输出配置 @@ -101,12 +101,15 @@ android { // 创建 WinBoLL Studio 发布接口文件夹 File fWinBoLLStudioDir = file("/sdcard/WinBoLLStudio/APKs"); + // 如果配置了APK接口文件夹路径,就设置应用APK输出文件夹为接口文件夹。 + if(winbollProps != null && winbollProps['APKOutputPath'] != null ) { + fWinBoLLStudioDir = file(winbollProps['APKOutputPath']); + } + if(!fWinBoLLStudioDir.exists()) { - //fWinBoLLStudioDir.mkdirs(); - // 如果没有发布接口文件就不用进行APK发布和源码管理操作 - // 当前编译环境不是 WinBoLL 主机, 以下将忽略APK发布和源码管理操作。 - println 'The current compilation environment is not in WinBoLL host, and the following APK publishing and source management operations will be ignore.' - } else { + println "[ WinBoLLStudio ] : " + fWinBoLLStudioDir.getAbsolutePath() + " Folder does not exist." + println '[ WinBoLLStudio ] : The APKOutputPath property is not defined in winboll.properties, please configure APK output folder first.' + } else { /// WINBOLL 主机的 APK 发布和源码管理操作 /// variant.getAssembleProvider().get().doFirst { /* 后期管理预留代码 */ diff --git a/LICENSE-Private-Demo b/LICENSE-Private-Demo new file mode 100644 index 0000000..dc5f366 --- /dev/null +++ b/LICENSE-Private-Demo @@ -0,0 +1,97 @@ +# WinBoLL 源码 LICENSE-Private-Demo 规范说明书 + +# LICENSE-Private-Demo + +# WinBoLL 源码公共转私有继承开发规范守则 + +## 核心声明 + +本文档**唯一核心设计目的**:通过文件标识、分支隔离、操作规范、责任界定四重约束,**从根源规避私有开发分支代码被人为合并、推送、提交至公共开源主流分支的风险**,明确人为操作失误、违规合并的全部责任归属,同时保证私有分支可正常同步、拉取公共主流分支的上游更新。 + +## 一、文件宗旨与风险防控说明 + +本文件为 WinBoLL 项目公共开源分支转为私有独立分支开发的**强制标准化操作手册与责任界定文件**,核心风控目标: + +1. 严格隔离公共开源分支与私有开发分支,通过授权文件标记实现分支属性一眼可辨,杜绝人为操作混淆 + +2. **重点防控人为操作导致的私有分支代码违规合并、回合、推送至公共 ****`winboll`**** 主流分支**,从流程上封堵合并风险 + +3. 明确所有开发提交者的操作责任,违规合并公共分支的行为由操作人承担全部代码泄露、合规风险 + +4. 规范私有分支初始化全流程,保证私有分支仅可单向同步公共分支更新,禁止任何反向代码流入公共分支 + +## 二、公私分支授权标识文件定义(风控核心依据) + +### 1. 公共开源分支唯一标识 + +**文件名:LICENSE** + +- 仅允许存在于公共主流分支 `winboll` 及官方公共衍生分支 + +- 标识当前分支为**开源公开可贡献分支**,遵循原开源授权协议 + +- **严禁私有分支内保留、恢复此文件**,出现即判定分支属性异常 + +### 2. 私有开发分支唯一标识 + +**文件名:LICENSE-Private** + +- 仅允许存在于私有开发分支,**绝对禁止出现在公共 ****`winboll`**** 分支** + +- 标识当前分支为**私有闭源分支**,代码仅限内部使用,禁止公开、禁止对外贡献 + +- 为本分支私有属性的法定判定依据,也是禁止合并至公共分支的核心标记 + +## 三、分支管理与合并风控规则(强制遵守) + +1. **公共主流分支**:固定为 `winboll`,为项目唯一开源主线,仅保留 `LICENSE` 文件,**禁止接收任何私有分支的合并、提交、推送请求**。 + +2. **私有开发分支**:统一从 `winboll` 分支检出,命名固定格式为 `private-demo-*`,与公共分支物理隔离。 + +3. **核心合并风控铁则** + + - 私有分支 → 公共分支:**永久禁止任何形式的合并、推送、PR 提交、代码回合,人为操作也绝不允许** + + - 公共分支 → 私有分支:允许正常拉取、同步上游更新,不影响私有开发迭代 + +4. 所有仓库提交者、合并操作者,均视为已阅读并完全认可本规则,**人为执行私有分支向公共分支的合并操作,由操作人承担全部代码泄露、合规违约、项目安全风险**。 + +## 四、公共转私有标准化操作步骤(锁死合并风险) + +请严格按顺序执行,每一步均为风控必要环节,不可跳过、不可修改顺序。 + +1. 基于公共主流分支 `winboll`,新建私有开发分支,严格使用 `private-demo-*` 命名,从名称上明确分支私有属性,避免人为混淆。 + +2. 本地仓库切换至新建私有分支,确认当前分支名称、检出来源无误。 + +3. **永久删除项目根目录公共授权文件 ****`LICENSE`**,彻底移除公共分支标识,断绝误合并的标识漏洞。 + +4. 将本规范文件 `LICENSE-Private-Demo` 复制并重命名为 `LICENSE-Private`,作为私有分支生效授权文件。 + +5. 将以上所有变更执行一次性 Git 提交,**提交信息必须固定使用以下内容,不可修改**: + + > 初始化私有开发分支,已切换私有授权文件,本分支禁止任何人为合并、推送至 winboll 公共分支 + > + > + +6. 提交完成后,本分支正式转为私有开发状态,后续所有代码提交、分支合并、版本迭代,均严禁指向公共 `winboll` 分支。 + +## 五、人为操作责任界定(核心补充条款) + +1. 本分支所有开发者、代码提交者、分支合并操作者,均视为**完全知晓本分支的私有属性与合并禁令**,自愿遵守本规范全部约束。 + +2. **无论故意或过失,凡是人为执行私有分支向公共 ****`winboll`**** 分支的合并、推送、PR 提交、代码回合操作,全部责任由执行操作的本人独立承担**,项目方不承担任何因人为违规操作导致的代码泄露、开源合规、版本污染风险。 + +3. 仓库管理员需严格校验合并请求的分支标识与授权文件,发现带有 `LICENSE-Private` 标记的分支申请合并至公共分支,一律直接拒绝,并记录操作人信息。 + +4. 分支属性校验以根目录授权文件为唯一标准:只要分支内存在 `LICENSE-Private` 文件,就绝对禁止向公共分支发起任何合并操作。 + +## 六、分支状态校验与异常处理 + +- 合规公共分支:仅存在 `LICENSE`,无 `LICENSE-Private` + +- 合规私有分支:仅存在 `LICENSE-Private`,无 `LICENSE` + +- 异常状态:两个文件同时存在 / 均不存在 → 立即停止开发与提交,按本规范重置分支状态,严禁执行任何合并操作 + +> (注:文档部分内容可能由 AI 生成) diff --git a/LICENSE-Private-Demo_docs/LICENSE-Private-Demo b/LICENSE-Private-Demo_docs/LICENSE-Private-Demo new file mode 100644 index 0000000..dc5f366 --- /dev/null +++ b/LICENSE-Private-Demo_docs/LICENSE-Private-Demo @@ -0,0 +1,97 @@ +# WinBoLL 源码 LICENSE-Private-Demo 规范说明书 + +# LICENSE-Private-Demo + +# WinBoLL 源码公共转私有继承开发规范守则 + +## 核心声明 + +本文档**唯一核心设计目的**:通过文件标识、分支隔离、操作规范、责任界定四重约束,**从根源规避私有开发分支代码被人为合并、推送、提交至公共开源主流分支的风险**,明确人为操作失误、违规合并的全部责任归属,同时保证私有分支可正常同步、拉取公共主流分支的上游更新。 + +## 一、文件宗旨与风险防控说明 + +本文件为 WinBoLL 项目公共开源分支转为私有独立分支开发的**强制标准化操作手册与责任界定文件**,核心风控目标: + +1. 严格隔离公共开源分支与私有开发分支,通过授权文件标记实现分支属性一眼可辨,杜绝人为操作混淆 + +2. **重点防控人为操作导致的私有分支代码违规合并、回合、推送至公共 ****`winboll`**** 主流分支**,从流程上封堵合并风险 + +3. 明确所有开发提交者的操作责任,违规合并公共分支的行为由操作人承担全部代码泄露、合规风险 + +4. 规范私有分支初始化全流程,保证私有分支仅可单向同步公共分支更新,禁止任何反向代码流入公共分支 + +## 二、公私分支授权标识文件定义(风控核心依据) + +### 1. 公共开源分支唯一标识 + +**文件名:LICENSE** + +- 仅允许存在于公共主流分支 `winboll` 及官方公共衍生分支 + +- 标识当前分支为**开源公开可贡献分支**,遵循原开源授权协议 + +- **严禁私有分支内保留、恢复此文件**,出现即判定分支属性异常 + +### 2. 私有开发分支唯一标识 + +**文件名:LICENSE-Private** + +- 仅允许存在于私有开发分支,**绝对禁止出现在公共 ****`winboll`**** 分支** + +- 标识当前分支为**私有闭源分支**,代码仅限内部使用,禁止公开、禁止对外贡献 + +- 为本分支私有属性的法定判定依据,也是禁止合并至公共分支的核心标记 + +## 三、分支管理与合并风控规则(强制遵守) + +1. **公共主流分支**:固定为 `winboll`,为项目唯一开源主线,仅保留 `LICENSE` 文件,**禁止接收任何私有分支的合并、提交、推送请求**。 + +2. **私有开发分支**:统一从 `winboll` 分支检出,命名固定格式为 `private-demo-*`,与公共分支物理隔离。 + +3. **核心合并风控铁则** + + - 私有分支 → 公共分支:**永久禁止任何形式的合并、推送、PR 提交、代码回合,人为操作也绝不允许** + + - 公共分支 → 私有分支:允许正常拉取、同步上游更新,不影响私有开发迭代 + +4. 所有仓库提交者、合并操作者,均视为已阅读并完全认可本规则,**人为执行私有分支向公共分支的合并操作,由操作人承担全部代码泄露、合规违约、项目安全风险**。 + +## 四、公共转私有标准化操作步骤(锁死合并风险) + +请严格按顺序执行,每一步均为风控必要环节,不可跳过、不可修改顺序。 + +1. 基于公共主流分支 `winboll`,新建私有开发分支,严格使用 `private-demo-*` 命名,从名称上明确分支私有属性,避免人为混淆。 + +2. 本地仓库切换至新建私有分支,确认当前分支名称、检出来源无误。 + +3. **永久删除项目根目录公共授权文件 ****`LICENSE`**,彻底移除公共分支标识,断绝误合并的标识漏洞。 + +4. 将本规范文件 `LICENSE-Private-Demo` 复制并重命名为 `LICENSE-Private`,作为私有分支生效授权文件。 + +5. 将以上所有变更执行一次性 Git 提交,**提交信息必须固定使用以下内容,不可修改**: + + > 初始化私有开发分支,已切换私有授权文件,本分支禁止任何人为合并、推送至 winboll 公共分支 + > + > + +6. 提交完成后,本分支正式转为私有开发状态,后续所有代码提交、分支合并、版本迭代,均严禁指向公共 `winboll` 分支。 + +## 五、人为操作责任界定(核心补充条款) + +1. 本分支所有开发者、代码提交者、分支合并操作者,均视为**完全知晓本分支的私有属性与合并禁令**,自愿遵守本规范全部约束。 + +2. **无论故意或过失,凡是人为执行私有分支向公共 ****`winboll`**** 分支的合并、推送、PR 提交、代码回合操作,全部责任由执行操作的本人独立承担**,项目方不承担任何因人为违规操作导致的代码泄露、开源合规、版本污染风险。 + +3. 仓库管理员需严格校验合并请求的分支标识与授权文件,发现带有 `LICENSE-Private` 标记的分支申请合并至公共分支,一律直接拒绝,并记录操作人信息。 + +4. 分支属性校验以根目录授权文件为唯一标准:只要分支内存在 `LICENSE-Private` 文件,就绝对禁止向公共分支发起任何合并操作。 + +## 六、分支状态校验与异常处理 + +- 合规公共分支:仅存在 `LICENSE`,无 `LICENSE-Private` + +- 合规私有分支:仅存在 `LICENSE-Private`,无 `LICENSE` + +- 异常状态:两个文件同时存在 / 均不存在 → 立即停止开发与提交,按本规范重置分支状态,严禁执行任何合并操作 + +> (注:文档部分内容可能由 AI 生成) diff --git a/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.docx b/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.docx new file mode 100644 index 0000000..0859049 Binary files /dev/null and b/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.docx differ diff --git a/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.pdf b/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.pdf new file mode 100644 index 0000000..10c3c11 Binary files /dev/null and b/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.pdf differ diff --git a/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.txt b/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.txt new file mode 100644 index 0000000..e191e48 --- /dev/null +++ b/LICENSE-Private-Demo_docs/WinBoLL_源码_LICENSE-Private-Demo_规范说明书.txt @@ -0,0 +1,97 @@ +# WinBoLL 源码 LICENSE\-Private\-Demo 规范说明书 + +# LICENSE\-Private\-Demo + +# WinBoLL 源码公共转私有继承开发规范守则 + +## 核心声明 + +本文档**唯一核心设计目的**:通过文件标识、分支隔离、操作规范、责任界定四重约束,**从根源规避私有开发分支代码被人为合并、推送、提交至公共开源主流分支的风险**,明确人为操作失误、违规合并的全部责任归属,同时保证私有分支可正常同步、拉取公共主流分支的上游更新。 + +## 一、文件宗旨与风险防控说明 + +本文件为 WinBoLL 项目公共开源分支转为私有独立分支开发的**强制标准化操作手册与责任界定文件**,核心风控目标: + +1. 严格隔离公共开源分支与私有开发分支,通过授权文件标记实现分支属性一眼可辨,杜绝人为操作混淆 + +2. **重点防控人为操作导致的私有分支代码违规合并、回合、推送至公共 ****`winboll`**** 主流分支**,从流程上封堵合并风险 + +3. 明确所有开发提交者的操作责任,违规合并公共分支的行为由操作人承担全部代码泄露、合规风险 + +4. 规范私有分支初始化全流程,保证私有分支仅可单向同步公共分支更新,禁止任何反向代码流入公共分支 + +## 二、公私分支授权标识文件定义(风控核心依据) + +### 1\. 公共开源分支唯一标识 + +**文件名:LICENSE** + +- 仅允许存在于公共主流分支 `winboll` 及官方公共衍生分支 + +- 标识当前分支为**开源公开可贡献分支**,遵循原开源授权协议 + +- **严禁私有分支内保留、恢复此文件**,出现即判定分支属性异常 + +### 2\. 私有开发分支唯一标识 + +**文件名:LICENSE\-Private** + +- 仅允许存在于私有开发分支,**绝对禁止出现在公共 ****`winboll`**** 分支** + +- 标识当前分支为**私有闭源分支**,代码仅限内部使用,禁止公开、禁止对外贡献 + +- 为本分支私有属性的法定判定依据,也是禁止合并至公共分支的核心标记 + +## 三、分支管理与合并风控规则(强制遵守) + +1. **公共主流分支**:固定为 `winboll`,为项目唯一开源主线,仅保留 `LICENSE` 文件,**禁止接收任何私有分支的合并、提交、推送请求**。 + +2. **私有开发分支**:统一从 `winboll` 分支检出,命名固定格式为 `private\-demo\-\*`,与公共分支物理隔离。 + +3. **核心合并风控铁则** + + - 私有分支 → 公共分支:**永久禁止任何形式的合并、推送、PR 提交、代码回合,人为操作也绝不允许** + + - 公共分支 → 私有分支:允许正常拉取、同步上游更新,不影响私有开发迭代 + +4. 所有仓库提交者、合并操作者,均视为已阅读并完全认可本规则,**人为执行私有分支向公共分支的合并操作,由操作人承担全部代码泄露、合规违约、项目安全风险**。 + +## 四、公共转私有标准化操作步骤(锁死合并风险) + +请严格按顺序执行,每一步均为风控必要环节,不可跳过、不可修改顺序。 + +1. 基于公共主流分支 `winboll`,新建私有开发分支,严格使用 `private\-demo\-\*` 命名,从名称上明确分支私有属性,避免人为混淆。 + +2. 本地仓库切换至新建私有分支,确认当前分支名称、检出来源无误。 + +3. **永久删除项目根目录公共授权文件 ****`LICENSE`**,彻底移除公共分支标识,断绝误合并的标识漏洞。 + +4. 将本规范文件 `LICENSE\-Private\-Demo` 复制并重命名为 `LICENSE\-Private`,作为私有分支生效授权文件。 + +5. 将以上所有变更执行一次性 Git 提交,**提交信息必须固定使用以下内容,不可修改**: + + > 初始化私有开发分支,已切换私有授权文件,本分支禁止任何人为合并、推送至 winboll 公共分支 + > + > + +6. 提交完成后,本分支正式转为私有开发状态,后续所有代码提交、分支合并、版本迭代,均严禁指向公共 `winboll` 分支。 + +## 五、人为操作责任界定(核心补充条款) + +1. 本分支所有开发者、代码提交者、分支合并操作者,均视为**完全知晓本分支的私有属性与合并禁令**,自愿遵守本规范全部约束。 + +2. **无论故意或过失,凡是人为执行私有分支向公共 ****`winboll`**** 分支的合并、推送、PR 提交、代码回合操作,全部责任由执行操作的本人独立承担**,项目方不承担任何因人为违规操作导致的代码泄露、开源合规、版本污染风险。 + +3. 仓库管理员需严格校验合并请求的分支标识与授权文件,发现带有 `LICENSE\-Private` 标记的分支申请合并至公共分支,一律直接拒绝,并记录操作人信息。 + +4. 分支属性校验以根目录授权文件为唯一标准:只要分支内存在 `LICENSE\-Private` 文件,就绝对禁止向公共分支发起任何合并操作。 + +## 六、分支状态校验与异常处理 + +- 合规公共分支:仅存在 `LICENSE`,无 `LICENSE\-Private` + +- 合规私有分支:仅存在 `LICENSE\-Private`,无 `LICENSE` + +- 异常状态:两个文件同时存在 / 均不存在 → 立即停止开发与提交,按本规范重置分支状态,严禁执行任何合并操作 + +> (注:文档部分内容可能由 AI 生成) diff --git a/LICENSE-Private-Demo_docs/long_pic_1778650008421587_503089827979333.jpg b/LICENSE-Private-Demo_docs/long_pic_1778650008421587_503089827979333.jpg new file mode 100644 index 0000000..77b5918 Binary files /dev/null and b/LICENSE-Private-Demo_docs/long_pic_1778650008421587_503089827979333.jpg differ diff --git a/README.md b/README.md index 4cb20e2..2c681b4 100644 --- a/README.md +++ b/README.md @@ -1,104 +1,105 @@ -WinBoLL 源生态计划项目说明书 +# WinBoLL 源生态计划项目说明书 + +## 一、项目概述 + +### 1. 核心定位 +WinBoLL 手机源码计划,旨在通过核心项目 WinBoLL 构建手机端与服务器端的 Android 项目的开发源码生态。实现手机与服务器的源码的联合开发。 + +### 2. 仓库架构 +#### **仓库类型:功能说明** +☆ 基础项目分支 WinBoLL:手机端安卓应用开发基础模板。 +☆ 应用项目分支 APPBase、AES、PowerBell、Positions**:安卓应用单一管理系列项目。 +☆ 源码汇总管理 OriginMaster**:各类分支源码合并存档,不适宜作为开发库使用。 + +### 3. 源码合并管理推送路线图 +⚠️ **注意**:仅仅展示不同应用模块源码的综合管理路线。分支合并操作时,必须具备 Git 管理经验。 + +★ WinBoLL → APPBase → OriginMaster +★ WinBoLL → AES → OriginMaster +★ WinBoLL → PowerBell → OriginMaster +★ WinBoLL → Positions → OriginMaster + +## 二、WinBoLL 项目核心信息 + +### 1. 项目简介 +☆ WinBoLL 项目是为手机端开发Android 项目的需求而设计的项目。 + +### 2. 官方资源 +#### ☆ 官方网站**:https://www.winboll.cc/ +#### ☆ 源码地址: +★ Gitea:https://gitea.winboll.cc/Studio/WinBoLL.git +★ GitHub:https://github.com/ZhanGSKen/WinBoLL.git +★ 码云:https://gitee.com/zhangsken/winboll.git + +## 三、应用编译环境检查问题 +### 核心判断条件: +☆ WinBoLL 项目以文件夹 `"/sdcard/WinBoLLStudio/APKs"` 是否存在为判断环境编译输出条件,因为编译输出的APK文件需要一个可供保存的环境。 + +☆ 文件夹"/sdcard/WinBoLLStudio/APKs" 目录条件设置方法: +***Linux 服务器端方面***:建立 `/sdcard/WinBoLLStudio/APKs` 目录即可。 +***手机开发端方面***:建立 `"/sdcard/WinBoLLStudio/APKs"` 目录(即 `"/storage/emulated/0/WinBoLLStudio/APKs"` 目录) 即可。 + +## 四、前置条件 + +### 1. WinBoLL APP 开发环境配置介绍 +#### WinBoLL APK 编译输出内容包括: +☆ "/sdcard/WinBoLLStudio/APKs"` 目录内的所有应用分支的 APK 文件。 +winboll.properties 文件的 APKOutputPath 属性可配置这个 APK 输出目录的路径。 +☆ "/sdcard/AppProjects/app.apk"文件。 +winboll.properties 文件的 ExtraAPKOutputPath 属性可配置这个 APK 额外输出文件的路径 +#### WinBoLL APK 源码命名空间规范 +☆ WinBoLL 项目使用 "cc.winboll.studio" 作为源码命名空间。在此命名空间下进行源码定义。 + +## 五、核心需求规划 + +### 1. WinBoLL 应用安全验证需求 +#### ☆ 支持访问 https://console.winboll.cc/ 服务器以校验应用包签名与版本。 + +### 2. 手机端源码开发管理需求 +#### ☆ 支持切换不同 WinBoLL 分支,以开发不同安卓应用。 + +## 六、编译与使用指南 + +### 1. 项目初始化(必须) +#### 1. 复制 `settings.gradle-demo` 为 `settings.gradle`。编辑 `settings.gradle` 文件内容,取消对应项目模块注释。 +#### 2. 复制 `gradle.properties-androidx-demo` (Android X 项目) 或 `gradle.properties-android-demo` (基本 Android 项目) 为 `gradle.properties`。 +#### 3. 复制(可选)`local.properties-demo` 为 `local.properties`,编辑 `local.properties` 文件内容,配置 Android SDK 目录。 +#### 4. **签名设置**: + ☆ **调试编译秘钥制作**:使用 Termux 应用终端,cd 进入 GenKeyStore 目录,运行 `bash gen_debug_keystore.sh` 脚本即可生成应用调试秘钥。 + ☆ **应用秘钥配置方法**:拷贝调试编译秘钥制作生成的 `appkey.jks` 与 `appkey.keystore` 文件到项目根目录即可。 + +## 七、应用编译命令介绍 + +### (1)类库型模块配置要点 +#### 1. **优先修改配置文件**:优先修改应用测试项目(目录为 `"/<类库测试应用>/"`)内 `build.properties` 文件,设置对应的类库项目名称:`libraryProject=<类库项目模块名>`。 +#### 2. **编译优先启动步骤**:使用 Termux 应用,进入 `""`,运行 `$ bash .winboll/bashPublishAPKAddTag.sh <类库测试项目模块名>` 命令。运行后可生成测试项目与类库项目的编译参数文件 `build.properties`。生成的 `build.properties` 文件有两份,一份在测试项目模块的文件夹内,一份在类库项目本身的模块文件夹内。 +#### 3. **最后类库编译发布步骤**:使用 Termux 应用,进入 `""`,运行 `$ bash .winboll/bashPublishLIBAddTag.sh <类库项目模块名>` 命令。运行后可发布至 WinBoLL Nexus Maven 库、本地 maven 目录或者是通用默认的 Gradle Maven 库。 + +### (2)单一应用型模块与类库测试型模块配置要点 +#### ☆ APK 编译方法: +使用 Termux 应用,进入 `""`,运行 `$ bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>`。 +#### ☆ 运行后的 APK 输出路径: +★ 默认路径 (`$ bash gradlew assembleBetaDebug` 任务):APK 在 `/sdcard/WinBoLLStudio/APKs/<项目根目录名称>/debug/` 目录。 +★ 默认路径 (`$ bash assembleStageRelease` 任务):APK 在 `/sdcard/WinBoLLStudio/APKs/<项目根目录名称>/tag/` 目录。 +★ 额外输出路径:(假设 `winboll.properties` 文件已配置 `ExtraAPKOutputPath` 属性) 输出至 `ExtraAPKOutputPath` 属性配置的目录下。 + +### (3)手机端应用调试命令介绍 +#### ☆ Beta 渠道调试命令 +$bash gradlew assembleBetaDebug + +#### ☆ Stage 渠道调试命令 +$bash gradlew assembleStageDebug + +### (4)服务器端开发命令介绍 +##### ☆ Stage 渠道应用发布命令为: +("/settings.gradle"文件需要配置编译模块开启参数,拷贝 settings.gradle-demo 为 settings.gradle 文件取消对应的分支配置部分即可。) +$bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  +或者是 +$bash gradlew assembleStageRelease -一、项目概述 - -1. 核心定位 - -【OriginMaster】WinBoLL 源生态计划,旨在通过核心项目 WinBoLL 联动系列开发库,构建手机端 Android 项目开发与多端编译同步的完整生态,实现手机与电脑的源码同步开发。 - -2. 仓库架构 - -仓库类型 包含仓库 功能说明 -开发库 WinBoLL、APPBase、AES、PowerBell、Positions 核心开发依赖库,其中 WinBoLL 可作为应用开发的基础继承模板 -分支汇总存档库 OriginMaster 仅用于汇总各开发库分支,不适宜作为开发库克隆使用,非应用开发基础库 - -3. 源码推送路径 - -- WinBoLL → APPBase → OriginMaster -- WinBoLL → AES → OriginMaster -- WinBoLL → PowerBell → OriginMaster -- WinBoLL → Positions → OriginMaster - -二、WinBoLL APP 核心信息 - -1. 项目简介 - -WinBoLL Studio Android 应用开源项目,专注于手机端 Android 开发与多端编译同步。 - -2. 官方资源 - -- 官方网站:https://www.winboll.cc/ -- 源码地址: -- Gitea:https://gitea.winboll.cc/Studio/WinBoLL.git -- GitHub:https://github.com/ZhanGSKen/WinBoLL.git -- 码云:https://gitee.com/zhangsken/winboll.git -- 托管类库源码: -- APPBase(jitpack.io):https://github.com/ZhanGSKen/APPBase.git -- AES(jitpack.io):https://github.com/ZhanGSKen/AES.git - -三、通用特征文件夹前置(/sdcard) - -- Linux 系统文件夹直接使用  /sdcard 。 -- 手机 SD 卡存储( /storage/emulated/0 )挂载的别名也可为  /sdcard 。 - -四、前置条件 - -1. WinBoLL-APP 配置 - -- APK 编译输出目录: /sdcard/WinBoLLStudio/APKs/ ,以及  /sdcard/AppProjects/ (命名为  app.apk ) -- 签名与命名空间:支持应用签名验证定制化,与衍生 APP 共享  cc.winboll.studio  命名空间 - -五、核心需求规划 - -1. 主机端需求 - -- 支持  winboll.cc  域名的用户注册登录服务 -- 支持  https://console.winboll.cc/api  访问 - -2. APP 端需求 - -- 实现手机端 Android 应用开发与管理功能 - -六、编译与使用指南 - -1. 项目初始化(必须) - -1. 复制  settings.gradle-demo  为  settings.gradle ,取消对应项目模块注释 -2. 复制  gradle.properties-androidx-demo  或  gradle.properties-android-demo  为  gradle.properties  -3. (可选)复制  local.properties-demo  为  local.properties ,配置 Android SDK 目录 -4. 签名设置: -- 调试编译:进入 GenKeyStore 目录执行  bash gen_debug_keystore.sh  -- 非必须:clone keystore 模块,拷贝  appkey.jks  与  appkey.keystore  到项目根目录 - -2. 编译命令 - -(1)类库型项目 - -1. 修改测试项目  build.properties ,设置  libraryProject=<类库项目模块名>  -2. 编译测试项目: bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  -3. 编译类库项目: bash .winboll/bashPublishLIBAddTag.sh <类库项目模块名> (发布至 WinBoLL Nexus Maven 库) - -(2)应用型项目 - -- 编译命令: bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  - -(3)调试编译 - -- Beta 调试: bash gradlew assembleBetaDebug  -- Stage 调试: bash gradlew assembleStageDebug -  -(4)发布编译 - -- Stage 发布:bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  - 或者执行  bash gradlew assembleStageRelease - -3. 编译输出路径 - -- 默认路径(assembleBetaDebug任务): /sdcard/WinBoLLStudio/APKs/<项目根目录名称>/debug/  -- 默认路径(assembleStageRelease任务): /sdcard/WinBoLLStudio/APKs/<项目根目录名称>/tag/  -- 额外路径:若  winboll.properties  配置  ExtraAPKOutputPath ,APK 同步拷贝至该ExtraAPKOutputPath路径 - -4. 版本号命名规则 - -- Stage 渠道: V<应用开发环境编号><应用功能变更号><应用调试阶段号> (示例: APPBase_15.7.0 ) -- Beta 渠道: V<应用开发环境编号><应用功能变更号><应用调试阶段号>-beta<调试编译计数>_<调试编译时间(分钟+秒钟)> (示例: APPBase_15.9.6-beta8_5413 ) + +## 八、WinBoLL 应用 APK 版本号命名规则 +### ☆ Stage 渠道: +#### V<应用开发环境编号><应用功能变更号><应用调试阶段号> (示例: APPBase_15.7.0 ) +### ☆ Beta 渠道: +#### V<应用开发环境编号><应用功能变更号><应用调试阶段号>-beta<调试编译计数>_<调试编译时间(分钟+秒钟)> (示例: APPBase_15.9.6-beta8_5413 ) diff --git a/aes/build.gradle b/aes/build.gradle index 899f105..8039c8c 100644 --- a/aes/build.gradle +++ b/aes/build.gradle @@ -24,13 +24,13 @@ android { defaultConfig { applicationId "cc.winboll.studio.aes" - minSdkVersion 21 + minSdkVersion 26 targetSdkVersion 30 versionCode 1 // versionName 更新后需要手动设置 // 项目模块目录的 build.gradle 文件的 stageCount=0 // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" - versionName "15.15" + versionName "15.20" if(true) { versionName = genVersionName("${versionName}") } diff --git a/aes/build.properties b/aes/build.properties index 7007fb4..4e746cb 100644 --- a/aes/build.properties +++ b/aes/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Tue Jan 13 03:37:56 HKT 2026 -stageCount=2 +#Tue May 12 13:11:28 HKT 2026 +stageCount=4 libraryProject=libaes -baseVersion=15.15 -publishVersion=15.15.1 +baseVersion=15.20 +publishVersion=15.20.3 buildCount=0 -baseBetaVersion=15.15.2 +baseBetaVersion=15.20.4 diff --git a/aes/src/main/AndroidManifest.xml b/aes/src/main/AndroidManifest.xml index c0ca77d..c732afa 100644 --- a/aes/src/main/AndroidManifest.xml +++ b/aes/src/main/AndroidManifest.xml @@ -3,6 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" package="cc.winboll.studio.aes"> + + + - * @Date 2026/01/11 15:16 + * @Date 2026/01/13 11:25 * @Describe 应用介绍窗口 */ -public class AboutActivity extends Activity { +public class AboutActivity extends BaseWinBoLLActivity { public static final String TAG = "AboutActivity"; + + private Toolbar mToolbar; + + @Override + public String getTag() { + return TAG; + } @Override protected void onCreate(Bundle savedInstanceState) { @@ -24,21 +31,33 @@ public class AboutActivity extends Activity { setContentView(R.layout.activity_about); // 设置工具栏 - Toolbar toolbar = findViewById(R.id.toolbar); - setActionBar(toolbar); - getActionBar().setSubtitle(TAG); - getActionBar().setDisplayHomeAsUpEnabled(true); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); // 点击导航栏返回按钮,触发 finish() - } - }); + initToolbar(); AboutView aboutView = findViewById(R.id.aboutview); aboutView.setAPPInfo(genDefaultAppInfo()); } + private void initToolbar() { + LogUtils.d(TAG, "initToolbar() 开始初始化"); + mToolbar = findViewById(R.id.toolbar); + if (mToolbar == null) { + LogUtils.e(TAG, "initToolbar() | Toolbar未找到"); + return; + } + setSupportActionBar(mToolbar); + mToolbar.setSubtitle(getTag()); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + mToolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + LogUtils.d(TAG, "导航栏 点击返回按钮"); + WinBoLLActivityManager.getInstance().resumeActivity(MainActivity.class); + WinBoLLActivityManager.getInstance().finish(AboutActivity.this); + } + }); + LogUtils.d(TAG, "initToolbar() 配置完成"); + } + private APPInfo genDefaultAppInfo() { LogUtils.d(TAG, "genDefaultAppInfo() 调用"); String branchName = "aes"; diff --git a/aes/src/main/java/cc/winboll/studio/aes/BaseWinBoLLActivity.java b/aes/src/main/java/cc/winboll/studio/aes/BaseWinBoLLActivity.java new file mode 100644 index 0000000..0526f82 --- /dev/null +++ b/aes/src/main/java/cc/winboll/studio/aes/BaseWinBoLLActivity.java @@ -0,0 +1,45 @@ +package cc.winboll.studio.aes; + +import android.app.Activity; +import android.os.Bundle; +import androidx.appcompat.app.AppCompatActivity; +import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity; +import cc.winboll.studio.libaes.models.AESThemeBean; +import cc.winboll.studio.libaes.utils.AESThemeUtil; +import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; + +/** + * @Author 豆包&ZhanGSKen + * @Date 2026/01/13 16:35 + * @Describe BaseWinBollActivity 【继承AppCompatActivity,保留核心能力,不额外暴露方法】 + * 继承链路:BaseWinBoLLActivity → AppCompatActivity → FragmentActivity,AppCompat能力天然继承可用 + */ +public abstract class BaseWinBoLLActivity extends AppCompatActivity implements IWinBoLLActivity { + public static final String TAG = "BaseWinBoLLActivity"; + + protected volatile AESThemeBean.ThemeType mThemeType; + + @Override + protected void onCreate(Bundle savedInstanceState) { + mThemeType = AESThemeBean.getThemeStyleType(AESThemeUtil.getThemeTypeID(getApplicationContext())); + setTheme(AESThemeUtil.getThemeTypeID(getApplicationContext())); + super.onCreate(savedInstanceState); + WinBoLLActivityManager.getInstance().add(this); + } + + @Override + protected void onDestroy() { + WinBoLLActivityManager.getInstance().registeRemove(this); + super.onDestroy(); + } + + // 子类必须实现getTag(),确保唯一标识 + @Override + public abstract String getTag(); + + @Override + public Activity getActivity() { + return this; + } +} + diff --git a/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java b/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java index 5360023..927c852 100644 --- a/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java +++ b/aes/src/main/java/cc/winboll/studio/aes/MainActivity.java @@ -30,7 +30,7 @@ import cc.winboll.studio.libappbase.LogUtils; import com.a4455jkjh.colorpicker.ColorPickerDialog; import java.util.ArrayList; -public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActivity { +public class MainActivity extends DrawerFragmentActivity { public static final String TAG = "MainActivity"; @@ -38,11 +38,6 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi TestAButtonFragment mTestAButtonFragment; TestViewPageFragment mTestViewPageFragment; - @Override - public Activity getActivity() { - return this; - } - @Override public String getTag() { return TAG; @@ -188,8 +183,9 @@ public class MainActivity extends DrawerFragmentActivity implements IWinBoLLActi Intent intent = new Intent(this, SettingsActivity.class); startActivity(intent); } else if (nItemId == R.id.item_about) { - Intent intent = new Intent(this, AboutActivity.class); - startActivity(intent); +// Intent intent = new Intent(this, AboutActivity.class); +// startActivity(intent); + WinBoLLActivityManager.getInstance().startWinBoLLActivity(this, AboutActivity.class); } diff --git a/aes/src/main/java/cc/winboll/studio/aes/WinBoLLActivity.java b/aes/src/main/java/cc/winboll/studio/aes/WinBoLLActivity.java index 76005db..bc45765 100644 --- a/aes/src/main/java/cc/winboll/studio/aes/WinBoLLActivity.java +++ b/aes/src/main/java/cc/winboll/studio/aes/WinBoLLActivity.java @@ -55,6 +55,6 @@ public class WinBoLLActivity extends AppCompatActivity implements IWinBoLLActivi @Override protected void onDestroy() { super.onDestroy(); - WinBoLLActivityManager.getInstance().registeRemove(this); + WinBoLLActivityManager.getInstance().finish(this); } } diff --git a/aes/src/main/res/drawable-night/bg_frame.xml b/aes/src/main/res/drawable-night/bg_frame.xml new file mode 100644 index 0000000..bf2fe54 --- /dev/null +++ b/aes/src/main/res/drawable-night/bg_frame.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + diff --git a/aes/src/main/res/drawable/bg_frame.xml b/aes/src/main/res/drawable/bg_frame.xml index 75b2b94..2f208a6 100644 --- a/aes/src/main/res/drawable/bg_frame.xml +++ b/aes/src/main/res/drawable/bg_frame.xml @@ -12,11 +12,7 @@ android:angle="270" android:endColor="#0F000000" android:startColor="#0F000000" /> - + @@ -31,11 +27,7 @@ android:angle="270" android:endColor="#0FFFFFFF" android:startColor="#FFFFFFFF" /> - + diff --git a/aes/src/main/res/layout/activity_about.xml b/aes/src/main/res/layout/activity_about.xml index bfd02eb..5cbe3fd 100644 --- a/aes/src/main/res/layout/activity_about.xml +++ b/aes/src/main/res/layout/activity_about.xml @@ -4,9 +4,9 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" android:background="@drawable/bg_container_border"> - diff --git a/aes/src/main/res/layout/activity_settings.xml b/aes/src/main/res/layout/activity_settings.xml index c8d3432..99dee06 100644 --- a/aes/src/main/res/layout/activity_settings.xml +++ b/aes/src/main/res/layout/activity_settings.xml @@ -4,7 +4,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" android:background="@drawable/bg_container_border"> + android:layout_height="match_parent" android:background="@drawable/bg_container_border"> + + + + + \ No newline at end of file diff --git a/aes/src/main/res/values/styles.xml b/aes/src/main/res/values/styles.xml index 1da88ba..267068a 100644 --- a/aes/src/main/res/values/styles.xml +++ b/aes/src/main/res/values/styles.xml @@ -1,5 +1,16 @@ - + + + \ No newline at end of file diff --git a/appbase/build.gradle b/appbase/build.gradle index 7d90452..b95d796 100644 --- a/appbase/build.gradle +++ b/appbase/build.gradle @@ -24,13 +24,13 @@ android { defaultConfig { applicationId "cc.winboll.studio.appbase" - minSdkVersion 21 + minSdkVersion 26 targetSdkVersion 30 versionCode 1 // versionName 更新后需要手动设置 // .winboll/winbollBuildProps.properties 文件的 stageCount=0 // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" - versionName "15.15" + versionName "15.20" if(true) { versionName = genVersionName("${versionName}") } diff --git a/appbase/build.properties b/appbase/build.properties index e17b41c..68642b1 100644 --- a/appbase/build.properties +++ b/appbase/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Tue Jan 13 03:23:34 HKT 2026 -stageCount=5 +#Tue May 12 09:17:15 HKT 2026 +stageCount=10 libraryProject=libappbase -baseVersion=15.15 -publishVersion=15.15.4 +baseVersion=15.20 +publishVersion=15.20.9 buildCount=0 -baseBetaVersion=15.15.5 +baseBetaVersion=15.20.10 diff --git a/appbase/src/beta/res/values/strings.xml b/appbase/src/beta/res/values/strings.xml index 024cdd2..49fc4c9 100644 --- a/appbase/src/beta/res/values/strings.xml +++ b/appbase/src/beta/res/values/strings.xml @@ -1,6 +1,6 @@ - AppBase+ + APPBase+ diff --git a/appbase/src/main/AndroidManifest.xml b/appbase/src/main/AndroidManifest.xml index f6a8420..4c0df09 100644 --- a/appbase/src/main/AndroidManifest.xml +++ b/appbase/src/main/AndroidManifest.xml @@ -9,27 +9,39 @@ android:label="@string/app_name" android:theme="@style/MyAPPBaseTheme" android:resizeableActivity="true" - android:process=":App"> + android:process=":App" + android:sharedUserId="@string/shared_user_id" + android:sharedUserLabel="@string/shared_user_label"> - - - - + + + + + + + * @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; + } +} + diff --git a/appbase/src/main/res/drawable/bg_container_border.xml b/appbase/src/main/res/drawable/bg_container_border.xml new file mode 100644 index 0000000..09c5bdf --- /dev/null +++ b/appbase/src/main/res/drawable/bg_container_border.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/appbase/src/main/res/layout-night/activity_about.xml b/appbase/src/main/res/layout-night/activity_about.xml new file mode 100644 index 0000000..f8af6b0 --- /dev/null +++ b/appbase/src/main/res/layout-night/activity_about.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/appbase/src/main/res/layout-night/activity_main.xml b/appbase/src/main/res/layout-night/activity_main.xml new file mode 100644 index 0000000..383caad --- /dev/null +++ b/appbase/src/main/res/layout-night/activity_main.xml @@ -0,0 +1,106 @@ + + + + + + + + + +