Kotlin Android 开发脚手架封装(模块化版本)

我将按照模块化设计原则,将脚手架拆分为多个文件,每个文件负责特定功能领域:

1. 核心初始化模块

文件路径: core/AppScaffold.kt

object AppScaffold {lateinit var context: Contextprivate setfun initialize(appContext: Context) {context = appContext.applicationContextinitLogger()NetworkModule.init(context)DatabaseModule.init(context)PreferencesModule.init(context)WorkManagerModule.init(context)AnalyticsModule.init()CrashReportingModule.init()}private fun initLogger() {Timber.plant(if (BuildConfig.DEBUG) Timber.DebugTree() else ReleaseLogTree())}private class ReleaseLogTree : Timber.Tree() {override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {// 生产环境日志实现(可集成Firebase/Crashlytics等)}}
}

2. 网络模块

文件路径: network/NetworkModule.kt

object NetworkModule {lateinit var retrofit: Retrofitprivate setfun init(context: Context) {retrofit = Retrofit.Builder().baseUrl(BuildConfig.BASE_URL).client(createOkHttpClient(context)).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(CoroutineCallAdapterFactory()).build()}private fun createOkHttpClient(context: Context): OkHttpClient {return OkHttpClient.Builder().connectTimeout(30, TimeUnit.SECONDS).readTimeout(30, TimeUnit.SECONDS).addInterceptor(LoggingInterceptor()).addInterceptor(AuthInterceptor()).addInterceptor(ConnectivityInterceptor(context)).build()}inline fun <reified T> createService(): T = retrofit.create(T::class.java)
}

3. 数据库模块

文件路径: persistence/DatabaseModule.kt

object DatabaseModule {lateinit var database: AppDatabaseprivate setfun init(context: Context) {database = Room.databaseBuilder(context,AppDatabase::class.java, "app-database").fallbackToDestructiveMigration().build()}
}

4. 偏好设置模块

文件路径: persistence/PreferencesModule.kt

object PreferencesModule {lateinit var preferences: SharedPreferencesprivate setfun init(context: Context) {preferences = EncryptedSharedPreferences.create(context,"secure_preferences",MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build(),EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM)}
}// 文件路径: `persistence/SessionManager.kt`
object SessionManager {var accessToken: String?get() = PreferencesModule.preferences.getString("access_token", null)set(value) = PreferencesModule.preferences.edit().putString("access_token", value).apply()var userId: Longget() = PreferencesModule.preferences.getLong("user_id", -1L)set(value) = PreferencesModule.preferences.edit().putLong("user_id", value).apply()
}

5. 后台任务模块

文件路径: work/WorkManagerModule.kt

object WorkManagerModule {lateinit var workManager: WorkManagerprivate setfun init(context: Context) {workManager = WorkManager.getInstance(context)}fun schedulePeriodicSync() {val constraints = Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).setRequiresBatteryNotLow(true).build()val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(repeatInterval = 1, repeatIntervalTimeUnit = TimeUnit.HOURS).setConstraints(constraints).build()workManager.enqueueUniquePeriodicWork("syncWork",ExistingPeriodicWorkPolicy.KEEP,syncRequest)}
}

6. 分析模块

文件路径: analytics/AnalyticsModule.kt

object AnalyticsModule {fun init() {// 初始化Firebase/Mixpanel等分析工具}fun trackEvent(eventName: String, params: Map<String, Any> = emptyMap()) {// 事件跟踪实现}
}

7. 崩溃报告模块

文件路径: crashreporting/CrashReportingModule.kt

object CrashReportingModule {fun init() {// 初始化Firebase Crashlytics/Sentry等}
}

8. 扩展函数模块

文件路径: extensions/ContextExtensions.kt

fun Context.showToast(message: String, duration: Int = Toast.LENGTH_SHORT) {Toast.makeText(this, message, duration).show()
}fun Context.isNetworkAvailable(): Boolean {val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerval network = connectivityManager.activeNetworkval capabilities = connectivityManager.getNetworkCapabilities(network)return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
}

9. 资源管理模块

文件路径: core/ResourceManager.kt

object ResourceManager {fun getString(@StringRes resId: Int, vararg args: Any): String {return AppScaffold.context.getString(resId, *args)}fun getColor(@ColorRes resId: Int): Int {return ContextCompat.getColor(AppScaffold.context, resId)}
}

10. 依赖注入模块

文件路径: di/ServiceLocator.kt

object ServiceLocator {private val services = mutableMapOf<String, Any>()inline fun <reified T : Any> register(instance: T) {services[T::class.java.name] = instance}inline fun <reified T : Any> get(): T {return services[T::class.java.name] as? T?: throw IllegalStateException("Service ${T::class.java.name} not registered")}
}

11. MVVM架构基础

文件路径: architecture/BaseActivity.kt

abstract class BaseActivity : AppCompatActivity() {abstract val layoutId: Intoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(layoutId)initView()initData()observeViewModel()}open fun initView() {}open fun initData() {}open fun observeViewModel() {}
}

文件路径: architecture/BaseViewModel.kt

abstract class BaseViewModel : ViewModel() {private val _isLoading = MutableLiveData<Boolean>()val isLoading: LiveData<Boolean> = _isLoadingprivate val _errorMessage = MutableLiveData<String>()val errorMessage: LiveData<String> = _errorMessageprotected fun showLoading() {_isLoading.postValue(true)}protected fun hideLoading() {_isLoading.postValue(false)}protected fun showError(message: String) {_errorMessage.postValue(message)hideLoading()}
}

12. 工具类模块

文件路径: utils/SecurityUtils.kt

object SecurityUtils {fun encrypt(data: String): String {// AES加密实现}fun decrypt(encryptedData: String): String {// AES解密实现}
}

文件路径: utils/ThemeManager.kt

object ThemeManager {fun applyTheme(context: Context, themeRes: Int) {context.setTheme(themeRes)// 动态主题应用逻辑}
}

使用示例

文件路径: MyApplication.kt

class MyApp : Application() {override fun onCreate() {super.onCreate()AppScaffold.initialize(this)// 注册服务ServiceLocator.register(DataRepositoryImpl())}
}

文件路径: MainActivity.kt

class MainActivity : BaseActivity() {override val layoutId = R.layout.activity_mainprivate val viewModel: MainViewModel by viewModels()override fun initData() {viewModel.loadData()}override fun observeViewModel() {viewModel.data.observe(this) { data ->// 处理数据}}
}

项目结构

app/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           ├── core/
│   │   │           │   ├── AppScaffold.kt
│   │   │           │   └── ResourceManager.kt
│   │   │           ├── network/
│   │   │           │   ├── NetworkModule.kt
│   │   │           │   └── interceptors/
│   │   │           ├── persistence/
│   │   │           │   ├── DatabaseModule.kt
│   │   │           │   ├── PreferencesModule.kt
│   │   │           │   └── SessionManager.kt
│   │   │           ├── work/
│   │   │           │   └── WorkManagerModule.kt
│   │   │           ├── analytics/
│   │   │           │   └── AnalyticsModule.kt
│   │   │           ├── crashreporting/
│   │   │           │   └── CrashReportingModule.kt
│   │   │           ├── di/
│   │   │           │   └── ServiceLocator.kt
│   │   │           ├── architecture/
│   │   │           │   ├── BaseActivity.kt
│   │   │           │   └── BaseViewModel.kt
│   │   │           ├── extensions/
│   │   │           │   └── ContextExtensions.kt
│   │   │           ├── utils/
│   │   │           │   ├── SecurityUtils.kt
│   │   │           │   └── ThemeManager.kt
│   │   │           ├── MyApplication.kt
│   │   │           └── MainActivity.kt
│   │   └── res/

这种模块化设计具有以下优点:

  1. 高内聚低耦合:每个模块专注于单一职责
  2. 易于维护:修改一个模块不影响其他功能
  3. 可扩展性强:添加新功能只需添加新模块
  4. 便于团队协作:不同开发者可并行开发不同模块
  5. 测试友好:模块可单独进行单元测试

这个脚手架封装了Android开发的核心基础设施,遵循现代Android开发最佳实践,可显著提高开发效率和代码质量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917910.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917910.shtml
英文地址,请注明出处:http://en.pswp.cn/news/917910.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter 报错解析:No TabController for TabBar 的完整解决方案

目录 Flutter 报错解析&#xff1a;No TabController for TabBar 的完整解决方案 一、错误场景&#xff1a;当 TabBar 失去 "指挥官" 二、为什么 TabBar 必须依赖 Controller&#xff1f; 1. TabBar 与 TabController 的协作关系 2. 状态管理的核心作用 3. 实战…

【24】C++实战篇——【 C++ 外部变量】 C++多个文件共用一个枚举变量,外部变量 extern,枚举外部变量 enum

文章目录1 方法2 外部变量 应用2.1 普通外部全局变量2.2 枚举外部全局变量 应用2.2.2 枚举外部变量优化c多个文件中如何共用一个全局变量 c头文件的使用和多个文件中如何共用一个全局变量 C共享枚举类型给QML 1 方法 ①头文件中 声明外部全局变量&#xff1b; ②在头文件对…

Linux SELinux 核心概念与管理

Linux SELinux 核心概念与管理一、SELinux 基本概念 SELinux 即安全增强型 Linux&#xff08;Security-Enhanced Linux&#xff09;&#xff0c;由美国国家安全局&#xff08;NSA&#xff09;开发&#xff0c;是一套基于强制访问控制&#xff08;MAC&#xff09;的安全机制&…

Git 中**未暂存**和**未跟踪**的区别:

文件状态分类 Git 中的文件有以下几种状态&#xff1a; 工作区文件状态&#xff1a; ├── 未跟踪 (Untracked) ├── 已跟踪 (Tracked)├── 未修改 (Unmodified) ├── 已修改未暂存 (Modified/Unstaged)└── 已暂存 (Staged)1. 未跟踪 (Untracked) 定义&#xff1a;Gi…

前端1.0

目录 一、 什么是前端 二、 HTML 1.0 概述 2.0 注释 三、开发环境的搭建 1.0 插件 2.0 笔记 四、 常见标签&#xff08;重点&#xff09; 四、案例展示&#xff08;图片代码&#xff09; 五、CSS引入 一、 什么是前端 web前端 用来直接给用户呈现一个一个的网页 …

Flutter镜像替换

一、核心镜像替换&#xff08;针对 Maven 仓库&#xff09; Flutter 依赖的 Google Maven 仓库&#xff08;https://maven.google.com 或 https://dl.google.com/dl/android/maven2&#xff09;可替换为国内镜像&#xff0c;常见的有&#xff1a;阿里云镜像&#xff08;推荐&am…

MATLAB实现的改进遗传算法用于有约束优化问题

基于MATLAB实现的改进遗传算法&#xff08;GA&#xff09;用于有约束优化问题的代码&#xff0c;包括处理非线性约束。此代码通过引入惩罚函数和修复机制&#xff0c;有效处理约束条件&#xff0c;提高算法的鲁棒性和收敛速度。 1. 定义优化问题 % 定义目标函数 function f ob…

Qt子类化QWidget后,使用setStyleSheet设置样式无效的解决方案

关键代码&#xff1a; #include <QPainter> #include <QStyleOption>void paintEvent(QPaintEvent *e) {QStyleOption opt;opt.init(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);QWidget::paintEvent(e); }定义…

【python中级】关于Flask服务在同一系统里如何只被运行一次

【python中级】关于Flask服务在同一系统里如何只被运行一次 1.背景 2.方案1 2.方案2 1.背景 python Flask实现的一个http服务,打包成应用程序exe后在windows10系统运行; 由于我会不断的更新这个http服务,我希望运行这个http服务的时候之前的http服务被停掉; 即实现 Pytho…

git配置公钥/密钥

遇到 “gitgithub.com: Permission denied (publickey)” 错误通常意味着你尝试通过 SSH 连接到 GitHub 时&#xff0c;SSH 密钥没有被正确设置或者 GitHub 无法识别你的公钥。这里有几个步骤可以帮助你解决这个问题&#xff1a; 检查 SSH 密钥 首先&#xff0c;确保你已经在本…

【机器学习】“回归“算法模型的三个评估指标:MAE(衡量预测准确性)、MSE(放大大误差)、R²(说明模型解释能力)

文章目录一、MAE、MSE、r概念说明二、MAE&#xff08;平均绝对误差&#xff09;&#xff1a;用"房价预测"理解误差测量三、MSE&#xff08;均方误差&#xff09;&#xff1a;误差的"放大镜"1、概念说明2、 sklearn代码实践3、流程总结四、R&#xff1a;理解…

智慧城市SaaS平台|市容环卫管理系统

【生活垃圾中转设施监管】1) 设施信息管理a) 设施基本信息支持记录中转设施的名称、位置、类型、容量、负责人等基本信息。b) 设施分布地图支持通过GIS地图展示中转设施的分布情况&#xff0c;支持地图查询和导航。2) 垃圾收运监控a) 垃圾收运记录支持记录垃圾收运的时间、车辆…

JAVA-13常用类(2025.08.02学习记录)

String类String类equals方法String类compareTo方法String类valueOf方法boolean参数内存分析_字符串拼接只会在内存中开辟一个对象内存分析_字符串new创建对象内存分析_变量和字符串拼接字节码执行过程String类内存分析package com.cn;public class test01 {public static void …

QT----简单的htttp服务器与客户端

HTTP协议学习 协议的相关学习可以参考这篇 csdn学习连接 总体流程如下 HTTP服务器 监听ip和端口,有连接时接收请求,发送回复 server.h #pragma once #include <QtWidgets/QMainWindow> #include "ui_httpServer.h" #include <QTcpServer> #include &l…

飞 算 JavaAI 解 析:有 了 它,麻 麻 再 也 不 用 担 心 我 不 会 写 代 码 了!

声 明&#xff1a;本 篇 博 客 为 测 评 体 验 非 广 告。 文 章 目 录一、产 品 简 介二、注 册 与 上 手方 法 一 - - - 从 IDEA 插 件 市 场 安 装方 法 二产 品 使 用三、产 品 体 验智 能 引 导 功 能理 解 需 求设 计 接 口表 结 构 设 计处 理 逻 辑生 成 源 码Java ch…

iOS混淆工具有哪些?在集成第三方 SDK 时的混淆策略与工具建议

许多 iOS 项目中&#xff0c;不可避免地会集成各种第三方 SDK&#xff0c;比如支付、统计、广告、社交登录等。这些 SDK 常常存在逆向被 Hook 或提取业务逻辑的风险&#xff0c;尤其是在流程敏感或要求合规的行业中。 当你无法对第三方源码进行控制或重新编译时&#xff0c;混淆…

【学习笔记之redis】删除缓存

有一串这个代码&#xff0c;staffEmailList这个key值里面的数据是错误的我需要删除它&#xff0c;把数据新的数据加载到redis缓存中。 public EmailAddressRespDTO getAllEmailAddress() { List<EmailAddressRespDTO> staffEmailList redisCache.getCacheList("s…

Redis 持久化机制浅析

1. 持久化机制的作用 Redis 是基于内存的数据结构数据库&#xff0c;虽然读写性能非常高&#xff0c;但所有数据默认保存在内存中。一旦服务器宕机、进程意外崩溃或容器重启&#xff0c;内存中的数据将全部丢失。这对于生产环境的可用性与可靠性是极其危险的。因此&#xff0c;…

使用MatterJs物理2D引擎实现重力和鼠标交互等功能,有点击事件(盒子堆叠效果)

使用MatterJs物理2D引擎实现重力和鼠标交互等功能&#xff0c;有点击事件&#xff08;盒子堆叠效果&#xff09; 效果图&#xff1a;直接上代码&#xff0c;我是用的是html&#xff0c;使用了MatterJs的cdn&#xff0c;直接复制到html文件中然后在浏览器打开即可 <!DOCTYPE …

如何玩转 Kubernetes K8S

在容器化时代&#xff0c;虽然Docker已经很强大了&#xff0c;但是在实际使用上还是有诸多不便&#xff0c;比如集群管理、资源调度、文件管理等等。 不过目前也涌现了很多解决方案&#xff0c;比如 Mesos、Swarm、Kubernetes 等等&#xff0c;其中谷歌开源的 Kubernetes就是其…