尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于 Android 的校园信息管理系统源码

基于 Android 的校园信息管理系统源码 摘要本文以一个面向高校的 Android 校园信息管理系统campusInfoApp为案例从架构设计、核心模块实现、关键技术选型三个维度展开分析详细阐述 MVP 分层、角色路由、主题换肤、网络封装等工程化实践为同类校园移动应用开发提供参考。一、项目概述1.1 项目背景随着高校信息化建设的推进学生和管理员对校园信息服务的需求日益多元化——新闻公告浏览、选课操作、请假审批、通知发布等功能分散在不同系统中用户体验割裂。本项目旨在构建一款一站式校园信息管理 Android 应用将多场景业务整合至统一入口。1.2 功能矩阵功能模块学生端管理员端用户体系注册 / 登录 / 个人信息 / 修改密码同左新闻公告浏览列表 查看详情发布 / 编辑 / 删除通知公告浏览列表 查看详情发布 / 管理请假管理提交请假申请含图片附件审批 / 查看列表选课系统课程查询 / 选课 / 已选课程查看添加课程 / 管理课程列表主题换肤三套皮肤切换经典/养眼/流行同左1.3 应用截图图 1 — 学生首页功能入口首页采用卡片式布局以图标文字的形式展示六大功能入口校园新闻、查询课表、请假、选课、发班级通知、微信订阅号。底部为自定义 RadioButton 导航栏首页/学生管理/我的管理员登录后自动显示学生管理Tab。图 2 — 注册页面注册页面支持头像上传通过 PictureSelector 选择相机或相册、用户名/昵称/性别/手机号/专业/密码等字段录入表单校验在客户端完成。图 3 — 课表查询页面课表查询以班级为单位展示软工1班~4班点击进入对应班级的课程详情数据来源于本地 SQLite 预置 远程服务端同步。二、技术栈与依赖2.1 基础配置配置项值Application IDcom.mmsx.campushcompileSdkVersion30targetSdkVersion29minSdkVersion21覆盖 Android 5.0源文件规模58 个 Java 文件 32 个布局 XML2.2 核心依赖// build.gradle 核心依赖implementationcom.squareup.okhttp3:okhttp:4.4.0// HTTP 客户端implementationcom.google.code.gson:gson:2.8.6// JSON 序列化implementationcom.github.bumptech.glide:glide:4.11.0// 图片加载implementationjp.wasabeef:glide-transformations:3.3.0// 图片变换圆角等implementationcom.github.LuckSiege.PictureSelector:picture_library:v2.6.0// 图片选择器implementationskin.support:skin-support:4.0.5// 换肤框架implementationandroidx.recyclerview:recyclerview:1.1.0// 列表组件说明build.gradle中声明了 Retrofit 和 RxJava 依赖但实际代码中网络层采用OkHttp 原生封装Okhttp.java单例工具类未使用 Retrofit/RxJava 组合。这属于开发过程中的技术决策调整——对于接口数量有限的中型应用直接使用 OkHttp 足够简洁高效。三、架构设计3.1 整体架构项目采用经典的Activity Fragment 主从结构辅以工具层和数据层的分层组织┌─────────────────────────────────────────────┐ │ UI 层 │ │ Activity (容器) → Fragment (内容页) │ │ BaseActivity → 具体业务 Activity │ ├─────────────────────────────────────────────┤ │ 适配器层 │ │ NewsAdapter / LeaveAdapter / SelectionAdapter ... ├─────────────────────────────────────────────┤ │ 工具层 │ │ Okhttp (网络) / SPUtils (持久化) │ │ GlideEngine (图片) / JsonUtils (解析) │ ├─────────────────────────────────────────────┤ │ 数据层 │ │ MySqliteOpenHelper (SQLite) │ │ Bean (数据实体) │ └─────────────────────────────────────────────┘3.2 应用启动流程应用启动时经历以下关键链路Application.onCreate() └─ SkinCompatManager 初始化换肤框架 ↓ OpenActivity (欢迎页) ├─ CountDownTimer 5秒倒计时 ├─ 检查 SPUtils.AUTO_LOGIN 是否启用 │ ├─ 是 → Okhttp.byAccount() 验证有效性 → MainActivity │ └─ 否 → LoginActivity ↓ LoginActivity ├─ 验证码生成随机4位字母数字 ├─ 记住密码 / 自动登录SPUtils 持久化 └─ Okhttp.byAccount() 远程验证 → 写入用户角色 → MainActivity ↓ MainActivity (主框架) ├─ 读取 SPUtils.USER_TYPE 判断角色 ├─ 学生 → [StudentHomeFragment, UserFragment] └─ 管理员 → [AdminHomeFragment, UserManageFragment, UserFragment]3.3 角色路由机制这是本项目的核心设计之一。MainActivity通过SharedPreferences中存储的USER_TYPE字段决定加载哪套 Fragment 组合// MainActivity.java - 角色判断逻辑userTypeConverterUtils.toInt(SPUtils.get(myActivity,SPUtils.USER_TYPE,));// 管理员隐藏学生管理Tab学生不显示rbManege.setVisibility(userTypeUserTypeEnum.User.getCode()?View.GONE:View.VISIBLE);// 我的Tab 根据角色映射到不同索引switchFragment(userTypeUserTypeEnum.User.getCode()?1:2);UserTypeEnum定义了三种角色类型枚举值含义导航 Tab 数量User(0)普通学生2 个首页 我的Admin(1)管理员3 个首页 学生管理 我的Dean(2)教学院长3 个同管理员Fragment 采用懒加载 show/hide模式避免重复创建privatevoidswitchFragment(intfragmentIndex){FragmentTransactiontransactiongetFragmentManager().beginTransaction();if(fragments[fragmentIndex]null){// 按角色创建对应 Fragment 实例fragments[fragmentIndex]userTypeUserTypeEnum.User.getCode()?newStudentHomeFragment()/newUserFragment():newAdminHomeFragment()/newUserManageFragment()/newUserFragment();transaction.add(R.id.ll_main_content,fragments[fragmentIndex]);}for(inti0;ifragments.length;i){if(fragmentIndex!ifragments[i]!null)transaction.hide(fragments[i]);// 隐藏其他 Fragment}transaction.show(fragments[fragmentIndex]);transaction.commit();}四、核心模块技术实现4.1 网络层封装OkHttp 工具类项目将 OkHttp 封装为单例工具类Okhttp.java统一管理所有 HTTP 交互publicclassOkhttp{privateStringhttphttp://192.168.3.6:8080/camplus/;// 服务端基础地址privatestaticOkhttpnetokhttp;publicfinalOkHttpClientclient;privateOkhttp(){clientnewOkHttpClient.Builder().readTimeout(2000,TimeUnit.MILLISECONDS)// 读超时 2s.connectTimeout(3000,TimeUnit.MILLISECONDS)// 连接超时 3s.build();}// 单例获取publicstaticOkhttppostNetokhttp(){...}}提供五种标准 REST 操作方法方法HTTP 动词用途postJson(url, json, callback)POST新增数据JSON BodyputJson(url, json, callback)PUT更新数据getJson(url, callback)GET查询列表deleteJson(url, id, callback)DELETE按 ID 删除uploadFile(path, callback)POST (Multipart)图片文件上传byAccount(account, callback)GET按账号查询用户所有请求均采用异步回调模式(enqueue(callback))在onResponse回调中通过JsonUtils将响应字符串反序列化为对应的 Bean 对象// 典型的调用模式Okhttp.postNetokhttp().byAccount(account,newCallback(){OverridepublicvoidonResponse(Callcall,Responseresponse)throwsIOException{Stringresresponse.body().string();UserResultresult(UserResult)JsonUtils.fromJson(res,UserResult.class);if(result!nullresult.getCode()0result.getData()!null){// UI 操作需切回主线程runOnUiThread(()-{...});}}});4.2 本地数据库SQLite 持久化通过MySqliteOpenHelper管理 6 张数据表-- 用户表CREATETABLEuser(idINTEGERPRIMARYKEY,account,password,name,sex,phone,room,photo,userType);-- 请假记录表CREATETABLEleave(idINTEGERPRIMARYKEY,userId,note,date,statue,path);-- 新闻表含已读/未读标记CREATETABLEnews(idINTEGERPRIMARYKEY,title,content,date,path,new,read);-- 通知表CREATETABLEnotice(idINTEGERPRIMARYKEY,title,content,date);-- 管理员课程表CREATETABLEadminCourse(idINTEGERPRIMARYKEY,number,name,credits,type);-- 学生已选课程表CREATETABLEstudentCourse(idINTEGERPRIMARYKEY,userId,number,name,credits,type);数据库初始化时预置了两个默认管理员账号admin/123教学院长/1233 条示例校园新闻黄冈师范学院相关内容2 条班级通知6 门示例课程大学语文、大学美术、中国近代史等静态变量mUser作为全局当前用户缓存登录成功后赋值各 Activity/Fragment 直接读取。4.3 主题换肤机制基于Android-SkinSupport开源框架实现运行时换肤分为三步第一步Application 初始化// MyApplication.javaSkinCompatManager.withoutActivity(this).addInflater(newSkinAppCompatViewInflater())// 基础控件拦截.addInflater(newSkinMaterialViewInflater())// Material Design 控件拦截.setSkinStatusBarColorEnable(false)// 关闭状态栏换肤.setSkinWindowBackgroundEnable(false)// 关闭 WindowBackground 换肤.loadSkin();第二步主题选择与保存// ThemeActivity.java - Spinner 选择主题ArrayListStringlistnewArrayList();list.add(经典主题);// index 0list.add(养眼主题);// index 1list.add(流行主题);// index 2spinner.setOnItemSelectedListener(newOnItemSelectedListener(){OverridepublicvoidonItemSelected(...){selectedTypeposition;SPUtils.put(activity,SPUtils.STUDENT_THEME,selectedType);// 持久化选择setTheme();// 应用主题}});第三步资源映射三套主题通过不同的 drawable 资源实现视觉差异如按钮背景btn_border_fill/btn_border_fill_1/btn_border_fill_2换肤框架根据当前选中索引动态加载对应资源。这种方式无需重启 Activity 即可生效。4.4 图片处理体系项目构建了一套完整的图片处理流水线PictureSelector (选择) ↓ GlideEngine (加载引擎实现 PictureSelector 的 ImageEngine 接口) ├── loadImage() → 普通/网络图片加载 ├── loadFolderImage() → 相册目录缩略图圆角 R8dp ├── loadGridImage() → 网格图片200x200 centerCrop ├── loadAsGifImage() → GIF 动图支持 └── 长图智能识别 → MediaUtils.isLongImg() 判断 ├─ 长图 → SubsamplingScaleImageView支持缩放/双击 └─ 普通图 → ImageView ↓ Okhttp.uploadFile() (上传至服务端) → MultipartBody FORM 表单上传关键设计点长图自适应通过判断宽高比自动切换到SubsamplingScaleImageView支持双击缩放和手势拖拽避免 OOM圆角缩略图相册目录页使用RoundedBitmapDrawableFactory设置 8dp 圆角头像上传请假申请时可附加图片证据通过MultipartBody上传至服务端/file/upload接口4.5 数据持久化SPUtils 工具类基于SharedPreferences封装的通用键值存储工具管理以下持久化项Key类型用途is_firstBoolean是否首次启动user_typeInteger用户角色0学生/1管理员/2院长user_idString当前登录账号last_nameString上次输入的用户名记住密码last_pswString上次输入的密码auto_loginBoolean自动登录开关remember_passwordBoolean记住密码开关student_themeInteger当前主题索引内部通过反射调用apply()方法实现异步提交并做了兼容性降级apply不可用时回退到commit。五、UI/UX 设计亮点5.1 自定义导航栏底部导航未使用BottomNavigationView而是采用RadioGroup RadioButton自定义方案每个 RadioButton 通过setCompoundDrawables()设置图标68x68 dp使用 Selector 资源实现选中/未选中状态切换颜色图标变化根据角色动态控制rbManege学生管理可见性这种方案的灵活性在于可以完全控制图标大小、间距和样式适合需要高度定制导航栏的场景。5.2 欢迎页倒计时OpenActivity实现 5 秒倒计时自动跳转同时支持点击跳过立即进入CountDownTimertimernewCountDownTimer(5000,1000){publicvoidonTick(longmillisUntilFinished){in.setText(millisUntilFinished/1000秒);}publicvoidonFinish(){finishView();// 时间到自动跳转}};跳转前会检查自动登录状态若之前勾选了自动登录且本地存有 userId则静默验证并直接进入主页否则进入登录页。5.3 双击退出MainActivity重写onKeyDown监听返回键实现双击退出间隔 2 秒publicvoidexit(){if(System.currentTimeMillis()-time2000){timeSystem.currentTimeMillis();Toast.makeText(myActivity,再点击一次退出应用程序,Toast.LENGTH_LONG).show();}else{finish();}}5.4 登录安全增强图形验证码每次进入LoginActivityonStart随机生成 4 位字母数字验证码纯客户端校验密码本地比对先远程拉取用户信息再在客户端做密码equalsIgnoreCase比较记住密码通过 SPUtils 持久化上次登录凭据复用 CheckBox 状态六、项目结构与代码组织6.1 包结构com.example.campus/ ├── MyApplication.java # Application 入口换肤初始化 ├── bean/ # 数据实体 │ ├── User / News / Leave / CourseSelection / StudentCourse │ └── *Result # 统一响应包装code data ├── enums/ # 枚举定义 │ ├── UserTypeEnum # 用户角色 │ ├── ComeTypeEnum # 请假去向类型 │ └── RepairsStatusEnum # 报修状态 ├── util/ # 工具类 │ ├── Okhttp.java # 网络请求封装单例 │ ├── SPUtils.java # SharedPreferences 封装 │ ├── MySqliteOpenHelper.java # 数据库管理 │ ├── JsonUtils.java # JSON 解析工具 │ ├── ConverterUtils.java # 类型转换工具 │ ├── GlideEngine.java # Glide 图片引擎 │ └── KeyBoardUtil.java # 键盘控制工具 ├── widget/ # 自定义控件 │ └── ActionBar.java # 统一标题栏组件 ├── adapter/ # RecyclerView 适配器 │ ├── NewsAdapter / NoticeAdapter │ ├── LeaveAdapter / CourseSelectionAdapter │ └── UserAdapter └── ui/ ├── activity/ # Activity 页面32个 │ ├── BaseActivity.java # 基类 │ ├── OpenActivity / LoginActivity / RegisterActivity │ ├── MainActivity # 主框架Fragment 容器 │ ├── ThemeActivity # 主题设置 │ ├── *News*Activity # 新闻相关学生浏览 管理员管理 │ ├── *Notice*Activity # 通知相关 │ ├── *Leave*Activity # 请假相关 │ ├── *Selection*Activity # 选课相关 │ └── PersonActivity / PasswordActivity └── fragment/ # Fragment 内容页 ├── StudentHomeFragment # 学生首页 ├── AdminHomeFragment # 管理员首页 ├── UserFragment # 个人中心 └── UserManageFragment # 用户管理管理员6.2 BaseActivity 基类所有 Activity 继承自BaseActivity统一处理公共逻辑如换肤兼容、ActionBar 绑定等保证各页面行为一致性。七、总结与展望7.1 技术亮点总结维度实践效果架构Activity Fragment 主从结构 角色路由一套代码适配学生/管理员双角色网络OkHttp 单例封装 异步回调统一接口风格超时可控存储SQLite 本地持久化 SharedPreferences 配置存储离线可用 用户偏好保留换肤Android-SkinSupport 运行时换肤无需重启即时生效图片PictureSelector Glide 长图智能识别全链路图片处理能力体验欢迎倒计时 / 双击退出 / 记住密码 / 自动登录符合移动端交互习惯7.2 可优化方向网络层升级可引入 Retrofit RxJava依赖已声明实现更优雅的链式调用和线程切换考虑添加拦截器统一处理 Token、日志、错误码架构现代化迁移至 Jetpack ComponentViewModel LiveData / Navigation Component替代手动 Fragment 管理和show/hide 模式数据库 ORM引入 Room 替代原生 SQLiteOpenHelper获得编译期 SQL 检查、LiveData 观察等能力模块化拆分按功能域news / notice / course / leave拆分为独立模块降低耦合度图片缓存策略结合 Glide 磁盘缓存与服务端 CDN优化图片加载性能安全加固密码传输加密HTTPS、Token 机制替代明文密码比对、服务端验证码替代客户端生成7.3 适用场景本项目的技术方案适用于以下类型的中小型 Android 应用开发企业/校园内部管理工具多角色权限的信息展示平台以列表浏览 表单提交为主的应用需要主题定制能力的 C 端产品本文基于 campusInfoApp 项目源码撰写截图来源于应用实际运行效果。
返回列表