我的项目树结构
根目录:/app/src/
以下是通过在根目录下运行 tree /f
命令输出的项目目录树,展示了包含文件的完整结构:
C:.
├───androidTest
│ └───java
│ └───com
│ └───example
│ └───alice
│ ExampleInstrumentedTest.kt
│
├───main
│ │ AndroidManifest.xml
│ │ ic_launcher-playstore.png
│ │
│ ├───java
│ │ └───com
│ │ └───example
│ │ └───alice
│ │ │ AboutFragment.kt
│ │ │ AIConfigFragment.kt
│ │ │ AlarmReceiver.kt
│ │ │ ApiService.kt
│ │ │ AppDatabase.kt
│ │ │ ChatFragment.kt
│ │ │ HistoryFragment.kt
│ │ │ LoggingFragment.kt
│ │ │ MainActivity.kt
│ │ │ MemoryFragment.kt
│ │ │ Message.kt
│ │ │ MessageAdapter.kt
│ │ │ PersonalizationFragment.kt
│ │ │ schedule.kt
│ │ │ ScheduleAdapter.kt
│ │ │ ScheduleDao.kt
│ │ │ ScheduleFragment.kt
│ │ │ SettingsAdapter.kt
│ │ │ SettingsData.kt
│ │ │ SettingsFragment.kt
│ │ │ Tools.kt
│ │ │ WebViewFragment.kt
│ │ │
│ │ └───ui
│ │ └───theme
│ │ Color.kt
│ │ Theme.kt
│ │ Type.kt
│ │
│ └───res
│ ├───animator
│ ├───color
│ │ bottom_nav_icon_tint.xml
│ │
│ ├───colors
│ ├───drawable
│ │ ic_launcher_background.xml
│ │ ic_launcher_foreground.xml
│ │ rounded_input_background.xml
│ │
│ ├───layout
│ │ activity_main.xml
│ │ dialog_add_schedule.xml
│ │ fragment_about.xml
│ │ fragment_ai_config.xml
│ │ fragment_chat.xml
│ │ fragment_history.xml
│ │ fragment_logging.xml
│ │ fragment_memory.xml
│ │ fragment_personalization.xml
│ │ fragment_schedule.xml
│ │ fragment_settings.xml
│ │ fragment_webview.xml
│ │ item_message.xml
│ │ item_schedule.xml
│ │ item_setting_category.xml
│ │ progress_dialog.xml
│ │
│ ├───main
│ ├───menu
│ │ bottom_nav_menu.xml
│ │
│ ├───mipmap-anydpi-v26
│ │ ic_launcher.xml
│ │ ic_launcher_round.xml
│ │
│ ├───mipmap-hdpi
│ │ ic_launcher.webp
│ │ ic_launcher_foreground.webp
│ │ ic_launcher_round.webp
│ │
│ ├───mipmap-mdpi
│ │ ic_launcher.webp
│ │ ic_launcher_foreground.webp
│ │ ic_launcher_round.webp
│ │
│ ├───mipmap-xhdpi
│ │ ic_launcher.webp
│ │ ic_launcher_foreground.webp
│ │ ic_launcher_round.webp
│ │
│ ├───mipmap-xxhdpi
│ │ ic_launcher.webp
│ │ ic_launcher_foreground.webp
│ │ ic_launcher_round.webp
│ │
│ ├───mipmap-xxxhdpi
│ │ ic_launcher.webp
│ │ ic_launcher_foreground.webp
│ │ ic_launcher_round.webp
│ │
│ ├───raw
│ ├───values
│ │ colors.xml
│ │ strings.xml
│ │ themes.xml
│ │
│ ├───values-v27
│ │ themes.xml
│ │
│ └───xml
│ backup_rules.xml
│ data_extraction_rules.xml
在项目根目录下打开命令行(cmd),输入 tree /f
即可生成上述包含文件名的目录树。
其中,com.example.alice
是应用的包名,位于 /com/example/alice/
路径下,包含了应用的核心代码文件。
典型的 Android 项目结构
Activity 文件:如 MainActivity.kt,作为应用的主入口,负责界面初始化和导航逻辑。
Fragment 文件:如 ChatFragment.kt、SettingsFragment.kt,实现模块化的 UI 和功能。
数据模型:如 Message.kt、SettingsData.kt,定义数据结构,通常是数据类(data class)。
适配器:如 MessageAdapter.kt、ScheduleAdapter.kt,用于 RecyclerView 的数据绑定。
工具类:如 Tools.kt,封装通用方法或逻辑,这里我封装了内置AI工具调用方法。
服务类:如 ApiService.kt,处理后台任务或网络请求。
数据库相关:如 AppDatabase.kt、ScheduleDao.kt,使用 Room 库管理本地数据。
主题文件:位于 ui/theme/ 下,如 Color.kt、Theme.kt,定义应用的视觉样式。
Kotlin
Kotlin 是安卓应用开发的主流编程语言之一,由 JetBrains 公司开发,因其简洁、安全和与 Java 的互操作性而受到广泛欢迎。在我的项目中,所有 .kt
文件(如 MainActivity.kt
、ChatFragment.kt
等)均使用 Kotlin 编写。
坦白说,我对 Kotlin 的掌握并不深入,目前仅能看懂代码,编写能力有限。因此,这里就不详细展开 Kotlin 的语法或特性了。如果你对 Kotlin 感兴趣,可以参考官方文档或一些入门教程,比如:Kotlin 官方文档。
gradle
把gradle放在最前面,就是因为它是必须先解决的问题。
Gradle 是安卓应用的构建工具,负责编译、打包、测试、发布等流程。在项目根目录下,有一个 build.gradle
文件,用于配置项目的编译环境、依赖库、打包方式等。
dependencies 是 Gradle 最常用的配置项,用于声明项目所依赖的库。例如:
plugins {
alias(libs.plugins.android.application)
id("org.jetbrains.kotlin.kapt")
}
android {
namespace = "com.example.alice"
compileSdk = 35
defaultConfig {
applicationId = "com.example.alice"
minSdk = 27
targetSdk = 35
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
}
实际上依赖要多的多的多,我省去了大部分方便看结构,但是也不用慌,你不需要知道需要什么依赖,需要什么,什么缺少引用了,鼠标移到依赖名上,就会提示你。
gradle更新后要重新同步,构建项目,有时候还要反复Clean Project,Rebuild Project。
AndroidManifest.xml
AndroidManifest.xml 是安卓应用的配置文件,位于 /app/src/main/ 目录下。它是应用的“身份证”,定义了应用的元数据、组件(如 Activity、Service、BroadcastReceiver 等)、权限要求等信息。安卓系统在安装和运行应用时会读取此文件。
在我的项目中,AndroidManifest.xml
定义了应用的包名、版本号、图标,并声明了主入口MainActivity,以及声明了需要的权限,主要包括联网权限、闹钟权限、存储读取权限等。
Activity
什么是 Activity?
Activity 是安卓应用的核心组件之一,代表用户与应用交互的一个界面。它本质上是一个窗口,可以包含各种视图(View,例如按钮、文本框)、处理用户输入(Input)、调用后台服务(Service)或接收广播(Broadcast)。在我的项目中,MainActivity.kt
是应用的入口 Activity。
Activity 的生命周期
MainActivity.kt
继承自 AppCompatActivity
类,实现了安卓标准的生命周期方法。这些方法用于控制 Activity 从创建到销毁的整个过程,主要包括:
**
onCreate()
**:
系统在 Activity 创建时调用,通常用于初始化 UI 组件,比如设置布局(setContentView()
)、绑定按钮点击事件等。在我的项目中,MainActivity
的onCreate()
负责加载activity_main.xml
并初始化底部导航栏。**
onStart()
**:
Activity 启动时调用,界面变得可见。通常用于启动一些后台任务,比如初始化音乐播放器或网络请求。**
onResume()
**:
Activity 从后台恢复到前台时调用,用户可以开始交互。此时适合恢复暂停的状态,例如继续播放音频。**
onPause()
**:
Activity 从前台切换到后台时调用(但仍可见),适合暂停耗时操作,比如暂停视频播放。**
onStop()
**:
Activity 完全不可见时调用,适合释放资源,例如关闭数据库连接或停止后台线程。**
onDestroy()
**:
Activity 销毁时调用,通常用于清理所有资源,比如关闭文件流或注销广播接收器。**
onRestart()
**:
Activity 从停止状态重新启动时调用,适合重新加载数据或恢复状态。
更多关于 AppCompatActivity
的方法,可以参考这篇博客:AppCompatActivity 方法详解。
与 Unity 的对比
安卓的生命周期有点类似 Unity 中的 void Start()
和 void Update()
,但侧重点不同。Unity 的逻辑更多集中在 Update()
的实时更新,而安卓应用倾向于在生命周期的早期(如 onCreate()
和 onStart()
)完成界面展示和内容加载。这种设计与安卓的用户使用习惯(如频繁切换应用)密切相关。
Fragment
什么是 Fragment?
Fragment 是依托于 Activity 的轻量级容器,可以看作是 Activity 的子模块。它拥有自己的 UI 组件和生命周期,可以动态嵌入 Activity 中,实现模块化和复用。
举例,ChatFragment.kt
、SettingsFragment.kt
等文件分别对应聊天、设置等功能模块,避免将所有逻辑堆积在单一的 Activity 中。
Fragment 的生命周期
Fragment 的生命周期与 Activity 类似,但多了与视图相关的回调。常用方法包括:
**
onCreateView()
**:
Fragment 创建时调用,返回其 UI 视图。通常用于加载布局文件(如fragment_chat.xml
)。**
onViewCreated()
**:
视图创建完成后调用,适合初始化控件或绑定数据。**
onActivityCreated()
**:
宿主 Activity 创建完成后调用,用于与 Activity 交互或加载数据。onStart()
和 **onResume()
**:
与 Activity 类似,分别表示 Fragment 启动和恢复。onPause()
和 **onStop()
**:
Fragment 暂停或停止时调用,用于暂停或释放资源。**
onDestroyView()
**:
Fragment 的视图销毁时调用,适合清理视图相关的资源。**
onDestroy()
**:
Fragment 销毁时调用,释放所有资源。**
onDetach()
**:
Fragment 从 Activity 分离时调用,通常是最后的清理步骤。
更多详情可参考:Fragment 生命周期详解。
为什么用 Fragment?
Fragment 的使用极大提高了代码的模块化程度。例如,ScheduleFragment
负责日程管理,ChatFragment
负责聊天功能,各自独立又能无缝切换,增强了用户体验。
Layout
什么是 Layout?
Layout 是安卓应用的视图层,定义了用户界面的结构和样式,位于 /res/layout/
目录下。每个 .xml
文件对应一个界面或组件的布局,例如 activity_main.xml
是主界面的布局文件,fragment_chat.xml
是聊天界面的布局文件。
命名规则
Layout 文件通常以 activity_
或 fragment_
开头,后接功能名称,例如 activity_main.xml
、fragment_settings.xml
。列表项布局则以 item_
开头,如 item_message.xml
。
常用属性
以下是 Layout 中常用的 XML 属性:
- **
android:id
**:控件唯一标识符,通过findViewById()
在代码中获取。 - **
android:layout_width
**:控件宽度,支持match_parent
、wrap_content
或具体单位(如dp
)。 - **
android:layout_height
**:控件高度,单位同上。 - **
android:layout_margin
**:控件外边距,控制与周围元素的间距。 - **
android:background
**:控件背景,可以是颜色(如#FFFFFF
)或 drawable 资源。
例如,在 fragment_chat.xml
中,我用 RecyclerView
显示消息列表,外层套了一个带圆角背景的 LinearLayout
,通过 rounded_input_background.xml
定义样式。
Service
什么是 Service?
Service 是安卓的后台组件,用于执行长时间运行的任务,不直接提供用户界面。在我的项目中,ApiService.kt
是一个典型的 Service 示例,可能用于处理网络请求或数据同步。
Service 的作用
Service 可以在 Activity 不可见时继续运行,例如:
- 后台下载文件。
- 定时同步数据。
- 播放音乐(如媒体播放器)。
我的ApiService
负责与硅基官方的服务器通信,接收的消息再返回进行多种处理方式。
Broadcast Receiver
什么是 Broadcast Receiver?
Broadcast Receiver 是安卓的广播接收器,用于接收系统或应用发送的广播消息。AlarmReceiver.kt
用于接收系统闹钟广播。
注册广播
在 AndroidManifest.xml
中,可以注册广播接收器,例如:
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
接收广播
在 BroadcastReceiver
类中,可以重写 onReceive()
方法,接收到广播后执行相应操作。
Adapter
Adapter 是安卓中用于将数据与视图(如 RecyclerView、ListView)绑定的桥梁。它负责将数据集合转换为可视化的列表项,并在用户交互时更新视图。在我的项目中,MessageAdapter.kt、ScheduleAdapter.kt 和 SettingsAdapter.kt 是Adapter,分别负责消息列表,日程列表和设置列表。
绑定数据
Adapter 绑定数据的方法有两种:
**
notifyDataSetChanged()
**:
直接通知 Adapter 数据集发生变化,Adapter 立即更新所有视图。**
notifyItemChanged(position)
**:
通知 Adapter 单个数据项发生变化,Adapter 仅更新该项视图。
布局文件
Adapter 的布局文件通常以 item_
开头,如 item_message.xml
。
Data
Data 通常指数据模型,用于定义应用中数据的结构。
在 Kotlin 中,常用 data class 来快速创建数据类,自动生成 toString()、equals()、hashCode() 等方法。
data class Message(
val id: Long,
val content: String,
val timestamp: Long,
val sender: String
)
Adapter 与 Data 的协作
Adapter 和 Data 是紧密相关的:
- 数据准备:Data(如 Message)存储在列表中。
- 数据传递:通过 Adapter 的构造函数或更新方法传入。
- 视图绑定:Adapter 将 Data 的字段映射到布局控件(如 textMessage.text = message.content)。
Database
数据库(Database)是安卓应用的本地数据存储,用于保存应用运行时产生的数据。Room 库是 Android Jetpack 中的一个组件,用于简化数据库操作。
数据库的作用
数据库的作用主要有以下几点:
- 保存应用运行时产生的数据。
- 缓存数据,提升应用的响应速度。
- 实现数据同步,实现多终端同步。
数据库的设计
数据库的设计通常分为三层:
- 实体层:定义数据结构,如
Message
、Schedule
、Settings
。 - DAO 层:定义数据库操作接口,如
MessageDao
、ScheduleDao
、SettingsDao
。 - 数据库层:实现数据库的创建、更新、查询等操作。
数据库加载应在后台线程(Dispatchers.IO)。
主题
什么是主题?
主题(Theme)是安卓应用的视觉风格,包括颜色、形状、字体、图标等。
安卓提供的常用主题类有:
Theme.Holo
:默认主题,包括深色背景和浅色文字。Theme.Holo.Light
:浅色主题,包括浅色背景和深色文字。Theme.Material
:Material Design 主题,包括深色背景和浅色文字。Theme.Material.Light
:Material Design 主题,包括浅色背景和深色文字。Theme.DeviceDefault
:Device Default 主题,包括深色背景和浅色文字。Theme.DeviceDefault.Light
:Device Default 主题,包括浅色背景和深色文字。Theme.AppCompat
:AppCompat 主题,包括深色背景和浅色文字。Theme.AppCompat.Light
:AppCompat 主题,包括浅色背景和深色文字。Theme.AppCompat.DayNight
:AppCompat 主题,包括深色背景和浅色文字,自动切换夜间模式。Theme.AppCompat.DayNight.DarkActionBar
:AppCompat 主题,包括深色背景和浅色文字,自动切换夜间模式,且状态栏变黑。
主题的切换
在 styles.xml
中,可以定义多个主题,并通过 android:theme
属性切换。例如:
<style name="AppTheme" parent="Theme.Material.Light.NoActionBar">
<!-- Application theme attributes -->
</style>
<style name="AppTheme.Dark" parent="Theme.Material.Dark.NoActionBar">
<!-- Application theme attributes -->
</style>
<application
android:name=".App"
android:theme="@style/AppTheme">
</application>
在 MainActivity
中,可以通过 setTheme()
方法切换主题:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTheme(R.style.AppTheme_Dark)
setContentView(R.layout.activity_main)
}
}
主题的设计
主题的设计通常分为三层:
- 颜色层:定义颜色,如
colorPrimary
、colorAccent
。 - 形状层:定义形状,如
shape
、corners
。 - 样式层:定义样式,如
style
。
其他
资源文件
除了以上介绍的资源文件,还有以下资源文件:
strings.xml
:字符串资源,用于定义应用的文本。colors.xml
:颜色资源,用于定义应用的颜色。styles.xml
:样式资源,用于定义应用的主题。dimens.xml
:尺寸资源,用于定义应用的尺寸。menu.xml
:菜单资源,用于定义应用的菜单。drawable
:图片资源,用于定义应用的图标。values
:其他资源文件,用于定义应用的其他资源。
因为内容过多,我之后会对各类组件和资源文件逐一进行介绍,还包括遇到的一些问题的解决。
[2025/3/5]太麻烦,我自己也不太懂,为避免误导,还有懒,就不写了。
此方悬停