Android应用目录结构全解析:从Gradle配置到资源文件管理
很多刚接触Android开发的朋友第一次用Android Studio新建项目时看到左侧那一大坨目录树往往会有点懵。我当年也是从一个个文件夹点开、再关掉折腾了好几天才搞清楚哪个目录是存代码的、哪个目录是放图片的、哪个文件是注册Activity的。这篇内容就把Android APP目录结构从上到下完整拆一遍讲清楚每个目录和文件的作用、它们之间如何配合以及我实际使用中总结出来的经验和容易踩的坑。不管你是刚入行的新手还是做了几年项目但很少动工程配置的老开发都值得花几分钟对照自己的项目看一遍。1. 从项目根目录说起那些你天天见到却不一定真正理解的配置文件1.1 新建项目后根目录到底有哪些文件和目录在Android Studio里新建一个空白项目默认会在项目根目录生成这样一批文件和目录我用一个比较典型的目录树来说MyApplication/ ├── .gradle/ ├── .idea/ ├── app/ ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── build.gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── local.properties ├── settings.gradle └── .gitignore先说两个带点的目录.gradle/和.idea/。前者是Gradle运行过程中产生的缓存和构建中间产物后者是Android Studio这个IDE自己的配置目录比如你窗口开多大、快捷键方案、最近的打开记录等。这两个目录的生命周期很“脆弱”——删了不会影响项目本身重新打开项目就能自动重建。真正影响工程是否正确的是下面这一堆没有点前缀的文件尤其是那几个gradle相关的文件。很多新手会把.gradle/和gradle/搞混。.gradle/是本地构建缓存本质上可以随意删除只是删了之后第一次构建会慢一些要重新下载依赖。而gradle/里面放着Gradle Wrapper的配置它是保证团队所有人构建版本一致的关键。这俩如果弄混要么卡在诡异的构建问题里要么不知不觉把本地缓存提交到代码仓库。1.2 settings.gradle从单模块到多模块的入口settings.gradle这个名字很直白就是工程的“设置脚本”。它最重要的职责是告诉Gradle这个项目里有哪些模块要参与构建。单模块项目里常见的内容大概是pluginManagement { repositories { google() mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } rootProject.name MyApplication include :app在较新的Gradle版本里pluginManagement和dependencyResolutionManagement这两个块被默认生成它们分别控制了“插件从哪里下载”和“依赖库从哪里下载”。include :app那一行是最核心的——它声明了app模块参与构建。如果你后面要加一个library模块通常就会在这里补一行include :library然后去对应目录创建它的build.gradle。rootProject.name设置的是项目名称这个名称会体现在构建输出的某些路径中。两个人用不同名称打开同一个工程不影响编译但如果你把项目改过名建议检查一下这里是否还和仓库里其他人保持一致否则和CI构建脚本对不上会很麻烦。1.3 gradle.properties与local.properties环境属性和项目属性的区别gradle.properties是Gradle的全局环境属性文件。它支持JVM参数、项目全局变量以及Android Gradle插件需要的一些开关。最常见的是这几行org.gradle.jvmargs-Xmx2048m -Dfile.encodingUTF-8 android.useAndroidXtrue android.enableJetifiertrueorg.gradle.jvmargs决定Gradle运行时的堆内存大小。默认的2G对小型项目够用但一个多模块项目构建到一半经常遇到内存不足这时把它调到4G甚至8G会明显改善。android.useAndroidXtrue表示全面使用新的AndroidX库体系现在新建项目基本都是默认开启的。如果这个属性是false而你代码里导入了AndroidX依赖编译会直接报错。local.properties则是纯本地的配置文件最典型的只有一行sdk.dir指向你机器上Android SDK的安装路径。它不应该提交到版本仓库里因为每个开发者的SDK路径是不同的提交后轻则每次拉代码都要改重则CI环境没有这个文件导致构建失败。我在这个环节踩过的一个坑某次把项目从一台电脑拷到另一台由于我记得把local.properties也拷贝过去了结果新电脑上SDK路径完全不对构建报了很多“找不到platform”的错误。排查了半天才发现是这个文件里的路径指向了不存在的目录。后来习惯是不管在哪个环境加载项目后第一时间查看local.properties的sdk.dir是否指向当前机器真实SDK位置。2. app模块目录日常开发的主战场2.1 build.gradle文件里三个区块的真实作用整个项目根目录下的build.gradle是项目级构建脚本通常只用来给所有子模块声明公共的插件或配置。真正决定app怎么编译、怎么打包、怎么处理依赖的是app/build.gradle。这个文件打开后基本是三个大区块plugins { id com.android.application } android { namespace com.example.myapplication compileSdk 34 defaultConfig { applicationId com.example.myapplication minSdk 23 targetSdk 34 versionCode 1 versionName 1.0 } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro } } } dependencies { implementation org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 }plugins块声明这个模块是应用模块还是库模块。com.android.application表示这是一个可以安装运行的APP如果是SDK或组件库对应的插件是com.android.library。android块里最值得关注的是namespace和defaultConfig。namespace是代码里R类和BuildConfig的包名而applicationId是最终安装到手机上的包名。平时两者保持一致比较简单省心但严格来说它们是两个概念你可以让applicationId改成上架版包名同时代码里的包结构保持原样。buildTypes里的release块主要就是开不开混淆minifyEnabled、用哪一套混淆规则proguardFiles。默认的proguard-rules.pro就是项目自己的规则文件如果你引用了第三方SDK经常需要在这里补充对应的-keep规则否则发布版可能一运行就闪退。许多新手发布版本出问题就是只改了minifyEnabled true却没往proguard-rules.pro里补足够的混淆白名单。dependencies就不多说了这里要提醒一个细节implementation和api的区别。implementation引入的依赖只在当前模块内部可见api则会把依赖传递到引用当前模块的其他模块。如果你在app模块里用implementation引入某个库而另一个library模块也在用这个库里的类编译时会报“无法访问”一类错误这时要么改api要么在依赖处也加上。2.2 java目录的包结构为什么推荐按功能分看一眼app/src/main/java下面的结构主要就是存放Kotlin或Java源码的。那个包名的多层目录看起来挺深但它不是随随便便拍脑袋定的——包名的前缀一般是公司域名反写加上项目名唯一标识整个应用的命名空间后面跟着的是业务模块的划分方式。推荐按功能划分包名比如com.example.myapplication/ ├── base/ ├── data/ │ ├── local/ │ ├── remote/ │ └── repository/ ├── ui/ │ ├── home/ │ ├── detail/ │ └── profile/ └── utils/这种划分的优点是模块边界清晰每个功能模块内部自己维护Activity、Fragment、ViewModel和Adapter而不是把所有Activity都扔到一个叫activity的包里。以前不少老项目喜欢按“类型”分activity、fragment、adapter、viewmodel看起来整齐但项目一大改动一个需求可能同时要跨三四个包修改找代码特别费劲。按功能分的好处就是改“首页”相关需求时所有相关类都在ui/home下面一眼看全。关于包名和目录结构有一个非常容易犯的错手动在java目录下新建了一个“包”但它实际上只是普通文件夹里面的类声明了package com.example.foo目录路径却不在对应位置。Android Studio会报“class is in the wrong module”类似的问题。正确做法是在包名上右键新建包或者在任意包上选New - Package不要直接在文件夹路径下瞎建。2.3 res目录的八大子目录与资源编译机制res目录是Android资源系统的核心它下面固定按类型分子目录。常见的子目录类别包括layout/XML布局文件values/字符串、颜色、尺寸、样式等键值对资源drawable-*dpi/位图或Shape等可绘制资源mipmap-*dpi/应用图标专用menu/菜单XMLanim/与animator/属性动画与补间动画的XMLxml/任意XML配置比如Preferences的配置文件raw/保持原样打包的二进制或文本资源font/字体文件资源所有res下的资源一旦被放在正确目录且命名合法Android构建时会自动生成一个R类里面每个资源都对应一个静态整数常量。你在代码里写的R.layout.activity_main、R.string.app_name本质上就是这些常量。这也决定了资源文件的命名必须严格遵守规则只能包含小写字母、数字、下划线不能以数字开头。你不要试图手动去改R类它在build/generated目录下每次构建自动生成。理解这一点能少走很多弯路有时候依赖本地build缓存出问题明明代码里写的是R.string.app_name却报找不到。清理一下项目重新构建R类重新生成就好了而不是去翻了代码半天以为引用写错。values目录下的XML有自己的嵌套格式strings.xml、colors.xml、dimens.xml通常分开文件放这纯粹是文件组织习惯并没有规定必须用这套文件划分。一个工程如果只有一个values.xml把所有字符串、颜色、尺寸全堆进去Gradle也能编译过只是维护体验很差。3. 最容易混淆的三类资源目录drawable、mipmap、assets3.1 mipmap和drawable的分工逻辑刚开始接触Android时我最大的困惑之一就是drawable和mipmap看起来都放图片为什么还要分成两个目录后来才明白这是Google的一种分工约定。mipmap目录专门放应用图标Launcher Icon。为什么图标要单独放一套因为Android桌面启动器会根据设备的不同分辨率去加载对应密度的图标比如从mipmap-mdpi到mipmap-xxxhdpi各放一张系统能自动选最合适的尺寸。如果你把图标放在drawable里往往也能正常工作但部分机型在某些场景下可能出现图标被缩放模糊的情况尤其是桌面快捷方式和通知栏图标。drawable则是更通用的“可绘制资源”目录。你可以放普通的PNG/JPG位图也可以放XML定义的矢量图VectorDrawable或形状图ShapeDrawable。drawable目录还会因为用途不同进一步分类比如drawable-hdpi、drawable-xhdpi或者带限定词的drawable-night表示夜间模式下的资源。这个后缀是Android资源限定机制的核心系统会综合设备的屏幕密度、语言、主题等信息选择最合适的资源文件。这里有个实际操作经验如果你有一张只会在某个固定控件里使用的小图标优先考虑矢量图放drawable而不是每种屏幕密度都准备一张PNG。矢量图是XML描述路径任意分辨率都不会糊而且体积通常更小。当然复杂的照片级图片还是用位图合适矢量图在这种场景下性能和效果都跟不上。3.2 assets目录不被资源系统管理的自由文件区assets目录和res最大的区别在于assets目录下的文件不会生成R类中的资源ID系统也不会做任何资源类型预定义它是一个纯粹的“原样打包区”。你放一个PDF进去打包后APK里就有这个PDF的原始内容放一个脚本打包后也原样存在。怎么读取assets下的文件要用原生文件IO通过AssetManager打开val inputStream assets.open(my_data.json) val content inputStream.bufferedReader().use { it.readText() }这和在res/raw下放文件再通过R.raw.my_data获取InputStream走的完全是两套机制。raw里的文件也保留原始格式但它是资源系统的一部分会生成资源ID可以参与资源限定和混淆重命名配置。assets更像一个普通的文件系统目录你可以自由创建任意子目录层次通过list()方法遍历目录这是raw做不到的它不支持子目录层级枚举。很多第三方SDK的初始化文件、字体文件、WebView里的本地网页资源经常放进assets。一个常见场景是WebView加载本地H5页面webView.loadUrl(file:///android_asset/dist/index.html)file:///android_asset/就是这个assets目录在运行时对应的URL前缀。有一回我把WebView的前端资源打进了assets测试时一直白屏后来发现是文件路径拼错了忘了把dist/子目录写上去。这个路径是写死的运行时协议名和代码文件目录没有关系排错时要分清楚。3.3 资源引用R类、文件路径和动态加载的差异当你想在代码里用某个资源时Android提供了好几种方式对应不同的使用场景。使用R类是编译期引用最常用、最快、最安全textView.setText(R.string.hello) imageView.setImageResource(R.drawable.ic_cat)使用反射或资源查找方式可以在运行时根据字符串名动态获取资源IDval id resources.getIdentifier(ic_cat, drawable, packageName)这种方式能解决一些特殊场景比如服务器下发了图片名你本地恰好有一批同名资源可以直接通过getIdentifier找到。但它比R类慢得多而且编译器无法检查资源是否存在很容易在运行时返回0导致找不到资源。只在不得不用的时候才用平时不要图方便滥用。还有一种是assets下的路径引用它不属于资源ID体系而是通过文件路径来读取。三种方式的本质区别是R类和getIdentifier走的是Android资源管理框架会经过资源选择、语言适配、主题处理而assets完全是原生文件读取不做任何适配。我建议在处理“应该随语言或屏幕密度变化的内容”时一定要用res系列资源处理“纯粹是文件、无需适配的内容”时放assets。两者职责清楚之后项目就不会出现“图片文件到底放哪”这类反复讨论的问题。4. AndroidManifest.xml把整个应用的骨架串起来4.1 四大组件的声明与意图过滤AndroidManifest.xml是Android应用的“总调度中心”它在src/main目录下所有应用级别的信息都要在这里登记。Android系统在安装一个APK时会读取这个文件它决定了你的APP拥有哪些入口、能做什么事情。四大组件——Activity、Service、BroadcastReceiver、ContentProvider——都必须在Manifest中显式声明一个都不能漏。以Activity为例最基本的声明是activity android:name.MainActivity /如果某个Activity要作为APP启动入口还要配置intent-filteractivity android:name.MainActivity intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity许多新手第一次做页面跳转时明明代码里startActivity写得很正常运行却报Unable to find explicit activity class之类的错误。十有八九就是忘了去Manifest里注册这个Activity。Android Studio的Manifest编辑器不会自动帮你把新建的Activity加进去每次新建一个组件都要养成手动检查一遍Manifest的习惯。intent-filter里除了MAIN和LAUNCHER可以做很多细活的适配。比如某些第三方SDK要求你做“分享回调”会要求你的Activity配置特定的action和category如果漏掉或写错回调就是收不到。这种问题不是编译能察觉的往往是运行时集成方Android平台回调失败排查起来非常浪费人力。4.2 权限声明与运行时权限的关系Manifest里另一个高频操作是权限声明。比如要做网络请求需要uses-permission android:nameandroid.permission.INTERNET /Android 6.0API 23之后系统引入了运行时权限机制INTERNET这类“普通权限”只要在Manifest声明安装后就有而“危险权限”比如读取联系人、访问相册、获取定位除了在Manifest里声明还需要在代码里动态申请用户同意后才能访问。这里很多人有一个错误认识以为在Manifest里声明了权限代码里直接调用就没问题了。实际对于危险权限如果只声明不动态申请在Android 6.0以上的设备上会直接抛SecurityException。正确的流程是先检查checkSelfPermission没有授权就弹窗requestPermissions最后在回调里确认结果。我处理过不少线上问题都是因为测试机是Android 5.0或更低版本危险权限直接授予代码跑得好好的用户升级到高版本设备后同样的代码直接闪退。所以在Manifest中声明权限之后一定要认真走一遍权限生命周期不要总觉得“声明了就行”。4.3 我在清单文件配置中踩过的几个坑按我个人的经验Manifest的问题往往比代码问题更隐蔽报错信息也常伪造。我印象比较深的有几次第一android:exported漏配。Android 12API 31以后如果某个Activity或Service带有intent-filter系统会强制要求指定android:exported的值。如果你的App兼容此版本一打开或安装阶段就可能直接崩。很多老项目从低版本targetSdk升级上来最容易栽在这里。第二application标签里的android:name指向Application子类但类路径写错了。最常见的情况是开启了混淆Application类被重命名或者内部类写法带了$符号最终导致系统启动就找不对Application。Manifest里的这些类路径必须和源码中的类真实路径一致。第三Manifest中重复注册Activity。多人协作时两个分支同时加了一个同名Activity或类路径写错但类名相似合并之后Manifest里出现两条相同name的注册记录Gradle会报“duplicate declaration”。这时候不要慌去Manifest里搜类名把多余的删掉就行。遇到Manifest相关错误我一般的排查顺序是先看日志里的完整异常是什么再对照Manifest检查组件是否声明、路径是否正确、exported是否设置。这三板斧熟练之后大多数清单类问题都能快速定位。5. 目录结构的演进从单模块到组件化以及版本管理中的细节5.1 为什么一个项目能有多个Module上面讲的都是默认的单模块结构也就是整个项目里只有一个app模块。真实商业项目中单模块往往不够用因为几十上百个开发者在同一个模块里协作合并冲突会非常痛苦。常见的做法是把项目拆成多个模块比如MyProject/ ├── app/ // 壳工程只负责组装和启动 ├── common/ // 基础库写通用工具、网络封装 ├── module_home/ // 首页业务模块 ├── module_mine/ // “我的”业务模块 └── module_login/ // 登录模块每个模块都有自己的src/main、自己的build.gradle、自己的AndroidManifest.xml。模块之间通过dependencies建立依赖关系比如app依赖module_home而module_home依赖common。这种结构下settings.gradle里的include会变成一大串include :app include :common include :module_home include :module_mine include :module_login拆模块不是把代码挪个目录那么简单。每个模块的build.gradle里如果也需要Glide、Retrofit等公共依赖通常会把公共依赖放到common模块的dependencies中其他模块再依赖common实现依赖传递。模块之间的Android资源命名也可能重复比如两个模块里都有activity_home.xml合在一起构建时会因为资源ID冲突而报错一般措施是统一资源前缀比如home_activity_main.xml、mine_activity_main.xml。我见过一些团队在“要不要拆模块”这个问题上反复拉扯。拆模块的前期成本确实高小项目没几个人拆了反而要来回改依赖。但等业务规模起来之后再拆成本更高。一般判断标准是团队人数超过10人或者核心业务需要同时多个版本迭代时就值得认真设计模块划分了。5.2 版本管理中的目录取舍目录结构还要考虑一个和Git相关的重要维度哪些目录和文件应该提交到版本库哪些应该忽略。一个健康的Android项目.gitignore通常要覆盖这些内容build/所有模块的构建输出目录不应该入库.gradle/本地Gradle缓存.idea/IDE本地配置多人协作时建议忽略避免窗口设置和文件监视器配置互相覆盖local.properties本地SDK路径*.iml旧的IDE模块文件新版一般也不怎么生成了有些开发者嫌麻烦直接把整个项目拖进Git.gitignore没配好结果build目录和.idea目录动辄几百MB甚至上GB的垃圾文件全部进了仓库。后面每个同事拉代码都会把大量不该有的文件下载下来仓库体积膨胀得厉害。更麻烦的是这些文件在不同机器上内容不稳定每次构建都会产生差异代码评审页面里全是无关的构建产物变更关键代码改动反而被淹没。仓库里真正应该被版本管理的是settings.gradle、两个build.gradle文件、gradle.properties、gradle/wrapper/、app/src/下的源码与资源以及像proguard-rules.pro这类配置文件。提交代码前养成看git status的习惯看到不该提交的文件提前处理能省很多客服同事的麻烦。5.3 目录命名与包名命名的实践经验最后分享一点命名层面的心得。Android的资源目录名和资源文件名是强行受约束的目录名如drawable-hdpi、values-zh-rCN都有严格规定。资源文件名只能小写字母、数字、下划线中划线不能用也不能用大写字母。Android Studio默认生成的模板遵循这套规则但我见过有人从Windows复制素材文件名自动带上了空格和大写扩展名放进drawable后构建直接报错。最快处理办法是用脚本来批量改名。包名命名有一点容易疏忽package名在Java/Kotlin文件里用点号分割但在AndroidManifest里配置组件时经常用相对名比如android:name.MainActivity。前面那个点表示“以当前模块的namespace为前缀”省去写完整包名的麻烦。但如果你把Activity放在一个很深的子包里这里的写法就要和namespace拼接起来例如android:name.ui.home.HomeActivity。写漏一层或者打头的点没写经常导致“类找不到”错误。资源和类文件还有一条隐藏约定不要在资源文件名或类型上“硬编码”业务含义的散装词。比如activity_login.xml和activity_login_main.xml放在同一个模块的layout目录里可读性是够的但数量多了很容易重名。比较好的做法是在文件命名时带上模块前缀如果你负责的是module_home布局就叫home_activity_main.xml如果你负责的是module_login就叫login_activity_main.xml。这样能最大程度地避开多模块合并时的重名冲突也让看到的同事不用点开内容就知道这个文件大概属于哪个业务块。目录结构这个主题看起来只是“文件夹排列”背后其实是整个构建系统面对你的约定和约束。理解了这些约束遇到很多“莫名其妙”的构建错误就有了排查方向不理解为啥这样设计就只能一直靠复制粘贴修错误。我建议你新建一个空项目对照我上面的内容把每个文件点开看一遍把每个目录对应到实际构建流程中真正跑通一次从创建到运行再到打包发布的过程。这个过程花不了半天时间但能从根本上把Android开发的地基打牢。之后遇到不认识的项目打开目录就能快速判断对方的技术选型和模块组织思路面试和接手老项目都不会再慌。

相关新闻

ecosim:基于C+OpenGL的生命演化模拟器实战指南

ecosim:基于C+OpenGL的生命演化模拟器实战指南

简介:ecosim是一款面向Linux平台开发者的交互式生态系统与进化模拟器,使用C语言与OpenGL实现,融合遗传算法、Boids群体行为模型等核心机制,适用于计算生物学、人工生命、复杂系统教学与算法可视化研究。资源包共24个文件&#xff…

2026/10/16 17:54:23 阅读更多 →
STM32驱动28BYJ-48步进电机:四相八拍时序与HAL底层优化实战

STM32驱动28BYJ-48步进电机:四相八拍时序与HAL底层优化实战

简介:本资源是一套基于STM32F10x系列芯片驱动28BYJ-48四相五线步进电机的完整嵌入式工程,面向嵌入式初学者、课程设计学生及单片机实践开发者,解决电机精准角度控制、正反转调速及软硬件协同调试等典型问题。压缩包共120个文件,总…

2026/10/16 17:54:23 阅读更多 →
银河麒麟V10离线部署DeepSeek:ARM无显卡纯CPU推理实战

银河麒麟V10离线部署DeepSeek:ARM无显卡纯CPU推理实战

简介:这份文档面向需要在银河麒麟V10(Kylin-Desktop-V10-SP1,ARM64架构)上离线部署大语言模型的技术人员,解决无外网或受限网络环境下搭建AI服务的问题。内容围绕ollama服务安装、deepseek-r1:14b蒸馏模型的离线下载与…

2026/10/16 17:54:23 阅读更多 →

最新新闻

VC++与MFC实现CAD绘图软件:源码解析与二次开发实践

VC++与MFC实现CAD绘图软件:源码解析与二次开发实践

简介:基于微软可视化C环境开发的仿AutoCAD绘图软件完整源代码,面向计算机图形学、Windows应用编程与CAD设计方向的开发者和学生,可用于课程设计、毕业设计或作为绘图工具的起步框架。项目实现了直线、圆、多边形、文字和圆弧等基础图元绘制&a…

2026/10/16 18:32:12 阅读更多 →
QPython Plus资源管理机制与OpenCV移动端部署指南

QPython Plus资源管理机制与OpenCV移动端部署指南

简介:本资源是面向Android移动开发者的Python轻量级运行环境增强包,专为在手机端开展Python 3编程学习与GUI应用开发而优化。它基于QPython Plus深度定制,预装Python 3.12.11解释器并原生支持Tkinter图形库,使用户无需PC即可编写、…

2026/10/16 18:32:12 阅读更多 →
Quartz集群生产落地:JDBCJobStore深度调优与避坑指南

Quartz集群生产落地:JDBCJobStore深度调优与避坑指南

1. 为什么Quartz的默认内存存储在生产环境里根本不能用刚接手某电商后台定时任务模块时,我看到配置文件里写着org.quartz.jobStore.class org.quartz.simpl.RAMJobStore,心里就咯噔一下。这不是把所有任务都塞进JVM堆内存里了吗?当时团队还觉…

2026/10/16 18:32:11 阅读更多 →
Hive窗口函数性能陷阱与优化实战指南

Hive窗口函数性能陷阱与优化实战指南

1. 问题现场还原:那个让整张报表卡住的窗口函数上周五下午三点,某数据中台团队的看板突然告警——一张核心日活漏斗表的ETL任务超时,重试三次后失败。运维同学甩来日志截图,最后一行赫然写着:FAILED: Execution Error,…

2026/10/16 18:32:11 阅读更多 →
多个Python文件打包成exe:PyInstaller与spec文件完整实践

多个Python文件打包成exe:PyInstaller与spec文件完整实践

先给结论:多个Python文件打包成exe这件事,并没有想象中那么玄乎,但也绝不是pyinstaller main.py一行命令就万事大吉。实际遇到的多模块项目、动态导入、资源文件、路径问题,都是会让你在交付前一夜失眠的东西。我大概从第一次给项…

2026/10/16 18:32:11 阅读更多 →
步步高家教机H8/H9/H10/S1/S2刷机工具包实战:固件识别与功能解锁

步步高家教机H8/H9/H10/S1/S2刷机工具包实战:固件识别与功能解锁

简介:这份资源是面向步步高家教机用户的破解工具包,适用于H8S、H9、H10、S1、S2等机型,主要解决家教机功能受限、无法自由安装应用的问题,可将设备恢复成普通平板使用,适合希望扩展家教机用途、具备一定动手能力的用户…

2026/10/16 18:31:10 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →