
簡介本資源是一套面向高校教師與計算機專業學生的Android課堂考勤系統完整開發包聚焦解決傳統點名易代答、統計難、反饋滯后等教學管理痛點。系統采用Android客戶端Web服務端雙入口設計支持人臉識別級照片核驗防代考實現考勤實時上傳、班主任動態查看、期末自動統計等功能適用于智慧校園信息化建設與課程設計實踐。壓縮包共403個文件含58張學生照片jpg/png、27個核心Java業務邏輯文件、89個編譯后class字節碼、25個Android布局與配置xml、24個PHP服務端接口腳本、14個前端交互js及配套css、1個可直接安裝的apk應用另有SQL建表語句、數據庫備份與多份配置備份文件.bak整體體積僅5.65MB結構清晰便于二次開發與部署。目前已有674人學習下載提供從客戶端到服務端再到數據庫的全鏈路源碼與文檔是Android移動開發與Web后端集成的典型教學案例。 課堂考勤這件事做過班委或者給老師當過助手的同學應該都有感觸。每到上課前幾分鐘教室里總會亂成一團點名冊傳來傳去代簽、漏簽、補簽的情況層出不窮。老師站在講臺上數人頭臺下學生低頭玩手機這種場景幾乎每所大學都在上演。我做過一版基于Android的大學生課堂考勤系統里面包括Android客戶端源碼、服務端源碼、數據庫設計文檔和整套說明文檔前后大概花了兩周時間完成屬于典型的課程設計或者畢業設計級別項目。這套系統不是停留在演示層面的玩具它把定位簽到、二維碼掃碼、請假審批、統計報表這些功能完整串了起來從手機端到后端服務再到數據庫落庫鏈路是通的。如果你正在糾結考勤系統怎么做或者想找一套能直接拿來改改用的完整源碼項目這篇文章會把這套系統的脈絡、關鍵代碼思路、數據庫設計邏輯和部署坑位全部拆開來講。先說清楚這套系統解決的核心問題傳統課堂考勤靠紙質點名或者口頭答到效率低、容易作弊、數據難統計。基于Android的考勤系統本質是把“老師點名”這件事數字化讓簽到動作發生在學生自己的手機上服務端負責記錄和判定數據庫負責持久化。這樣老師打開后臺就能看到出勤率、遲到名單、請假記錄學生打開手機App就能一鍵簽到管理員還能導出統計報表。整體鏈路不復雜但涉及的知識點覆蓋了Android界面開發、網絡請求、定位服務、二維碼掃描、服務端接口設計、數據庫表關系設計等剛好是一套標準的全棧練手項目。這套系統的受眾其實很明確一是計算機相關專業正在做課程設計或畢業設計的在校生二是想從前端或者單純Android方向往全棧靠一靠的開發者。你不需要有多深的架構經驗只要會Java基礎、了解Android基本組件再稍微懂點SQL和Spring框架就能跟著源碼把這套系統跑起來。下面我按模塊拆開講每個部分都會結合我實際開發時踩過的坑和調整過的方案來說。1. 項目整體設計與思路拆解1.1 核心需求與功能定位做任何項目之前先把需求邊界劃清楚不然做到一半就會失控。這套考勤系統的核心用戶有三類學生、教師、系統管理員。學生的核心操作是查看課程表、發起簽到、提交請假教師的核心操作是創建課程、發起考勤、查看簽到統計、審批請假管理員則負責基礎數據維護比如學生信息、教師信息、班級信息、課程信息的增刪改查。基于這些需求系統整體分為三個端Android客戶端學生和教師共用通過角色區分權限、服務端RESTful API、數據庫MySQL。沒有單獨做Web管理端教師端的部分功能通過Android客戶端完成管理員的批量數據維護則直接操作數據庫或者附加一個簡單管理頁面。這個取舍比較符合課程設計的工作量也避免了戰線拉太長導致做不完的問題。實際開發時需求邊界一定要寫清楚并和指導老師確認。我第一版做的時候野心很大想把視頻簽到、人臉識別、藍牙定位全塞進去結果發現工作量根本收不住。后來收斂到定位簽到掃碼簽到請假審批統計導出這四個核心功能項目才真正落地。這算是一條很實用的經驗畢設或課設項目優先保證核心鏈路完整而不是追求功能數量。1.2 技術選型與架構分層技術選型決定了下半程開發是輕松還是痛苦。客戶端我選了純Java Android原生開發沒有用Kotlin和Flutter原因很簡單課程設計階段絕大多數學校的教材和實驗環境還是Java為主改用Kotlin雖然寫起來更簡潔但會引入額外的學習成本和兼容性排查成本。網絡層使用OkHttp Gson沒有引入RxJava和Retrofit全家桶保證源碼讀起來直觀老師答辯問起來你也能講清楚每一個環節。服務端選型上Spring Boot 2.x是最穩的選擇。它內嵌了Tomcat減少了大量xml配置跑起來快資料也多。持久層用的是MyBatis沒有用Spring Data JPA因為MyBatis的SQL可讀性更強數據庫課上學的那些聯表查詢都能直接寫出來答辯時也能順勢展示SQL功底。數據庫用MySQL 5.7這是國內課設環境里最普及的版本8.0也兼容但一些驅動和連接配置會稍有差異。架構分層遵循標準的三層結構Android客戶端只負責界面展示和用戶交互通過HTTP協議調用服務端接口服務端按Controller、Service、Mapper分為三層統一處理業務邏輯和鑒權數據庫只負責數據存取。三層結構的好處是職責分離、定位問題快客戶端出問題查客戶端服務端接口報錯查服務端不用上下游來回猜。提示如果你打算基于這套源碼二次開發建議保持三層結構不動只替換具體業務邏輯。我見過不少同學為了圖省事把SQL直接寫在Controller里項目是跑通了但答辯被老師一追問就卡殼了。2. Android客戶端核心模塊解析2.1 客戶端工程結構與頁面規劃Android客戶端的包名規劃直接暴露了一個開發者對項目的理解是否清晰。這套系統的客戶端工程目錄劃分比較標準activity包存放頁面adapter包存放列表適配器entity包存放實體類network包封裝網絡請求utils包放工具類service包放后臺服務。四個核心頁面分別是登錄頁、首頁課程列表、簽到頁定位/掃碼、個人中心考勤記錄與請假。登錄頁承擔的是角色分發學生登錄后默認進入課程列表頁教師登錄后進入考勤管理頁。這里用了一個技巧——登錄接口返回的JSON里包含role字段客戶端拿到后直接緩存到SharedPreferences之后每次跳轉前都檢查一下角色。界面層面沒有做復雜的動畫和花哨的UI重點保證邏輯通順、控件命名規范。實際開發中頁面規劃的先后順序很重要。我的做法是先把登錄和課程列表跑通再往后加簽到和請假流程因為這兩個頁面是整個App的地基地基不穩后面全白搭。規劃頁面時強烈建議先畫一遍界面草圖哪怕是用紙筆把每個按鈕點擊后跳轉到哪里、每個列表項點擊后做什么都標記清楚代碼寫起來會順很多。2.2 網絡請求封裝與會話保持客戶端和服務端的交互全部走HTTP接口。這里不推薦直接在Activity里new OkHttpClient然后發請求代碼會冗余到沒法看。我封裝了一個HttpUtil工具類統一處理GET、POST請求、JSON解析和錯誤碼提示。核心思路是所有接口走同一個入口請求參數用HashMap傳遞返回結果統一用JsonObject包裝里面包含code、message、data三個字段。會話保持用Token機制。用戶登錄成功后服務端返回一個Token字符串客戶端把它緩存到SharedPreferences里后續每次請求都在Header里帶上Authorization字段。服務端通過攔截器校驗Token校驗通過才放行。這套機制實現簡單也能滿足移動端的身份認證需求。答辯的時候如果老師問“為什么用Token而不用Session”你就回答移動端不像瀏覽器有Cookie自動管理機制Token更輕量、跨端更友好。關于網絡請求的線程問題踩過不少坑。Android要求網絡請求不能在主線程執行否則會拋NetworkOnMainThreadException。所以封裝時必須用子線程發起請求拿到結果后再通過runOnUiThread切回主線程更新UI。更規范的方案是用Handler或者RxJava但對于課設來說runOnUiThread已經夠用。2.3 簽到模塊的兩種實現方式簽到是這套系統的靈魂功能。我實現了兩種簽到方式GPS定位簽到和二維碼掃碼簽到。GPS定位簽到適合老師要求學生在教室現場簽到的情況。原理很簡單客戶端通過LocationManager獲取經緯度上傳給服務端服務端和課程設置的簽到地點經緯度做距離計算距離小于設定閾值比如100米判定為有效簽到。這個方案實現成本低但有個明顯的坑——室內環境GPS信號弱定位偏差大。二維碼掃碼簽到解決的是“人不在現場但能定位”的問題。老師端打開課程后生成一個二維碼里面包含課程ID和當前時間戳學生用App內置的掃碼功能掃描二維碼服務端解析二維碼內容并校驗課程信息和時間段校驗通過就記為有效簽到。二維碼用zxing庫實現這個庫雖然已經好多年沒更新了但在離線掃碼場景下依然穩定可靠課程設計用完全沒有問題。兩種簽到方式我建議都保留因為不同課程的簽到場景不一樣。教室密集的實驗樓里GPS定位飄得離譜二維碼掃碼更可靠而體育館、操場這類室外場景沒有大屏幕展示二維碼GPS定位反而是更好的選擇。代碼層面兩種簽到共用同一個簽到成功頁只是數據來源不同這樣UI邏輯可以復用。注意定位簽到一定要處理權限請求。Android 6.0以上動態權限是繞不開的坑除了在AndroidManifest.xml里聲明權限還要在代碼里用requestPermissions動態申請否則在Android 9以上的設備上直接崩潰。這是我改了三次才徹底解決的問題。2.4 請假與考勤記錄的實現細節請假功能說起來簡單做起來也有不少細節。學生端提交請假申請填寫請假類型事假、病假、開始時間、結束時間、請假原因然后提交給服務端。服務端把請假記錄寫入leave_apply表狀態初始為0待審批。教師端能看到待審批的請假列表點擊審批后狀態變為1通過或2駁回。考勤記錄頁面是一個列表展示學生每一門課程的到課情況。這里服務端做了一個聯表查詢把course、attendance_record和學生信息關聯起來返回給客戶端一個帶有課程名、簽到時間、簽到狀態的對象列表。狀態用數字表示0未簽到、1正常、2遲到、3請假、4缺勤。遲到判定由服務端計算簽到時間晚于課程開始時間10分鐘則標記為遲到超過30分鐘直接標記為缺勤。這些狀態在客戶端展示時映射成對應的中文文本和顏色標識列表項的視覺區分非常清晰。3. 服務端接口與數據庫設計3.1 服務端框架與項目構建服務端基于Spring Boot搭建目前依賴了Web、MyBatis、MySQL驅動、Lombok這幾個核心組件。項目結構按標準的分層模式來寫controller包接收前端請求service包處理業務邏輯mapper包接口配合resources下的xml文件操作數據庫entity包對應數據表實體。構建工具使用Mavenpom.xml里配置了阿里云鏡像倉庫國內開發環境下下載依賴速度快很多。如果你想把這套服務端源碼在自己電腦上跑起來第一步就是確保Maven的settings.xml配置了合適的鏡像源否則依賴下載會非常痛苦。服務端啟動端口默認配置在8080可以通過application.yml修改。數據庫連接信息同樣在application.yml中配置包括URL、用戶名和密碼。這里要提醒一點不同學校機房MySQL的安裝方式不一樣密碼設置也千奇百怪最容易出的問題就是連接串里的密碼和本地數據庫不一致。調試的時候先確認服務端日志里有沒有報數據庫連接異常通過日志帶動排查是最快的方式。3.2 數據庫表結構設計詳解數據庫是整個系統最核心的部分表結構設計得好不好直接決定了后續功能能不能順暢擴展。這套系統一共設計了6張核心表表名用途關鍵字段user用戶表id, username, password, real_name, role, student_no, create_timecourse課程表id, course_name, teacher_id, course_time, location, latitude, longitude, sign_start_time, sign_end_timecourse_student學生選課表id, course_id, student_idattendance_record考勤記錄表id, course_id, student_id, sign_time, status, sign_typeleave_apply請假申請表id, student_id, course_id, reason, start_time, end_time, status, approver_idcourse_code簽到碼表id, course_id, code, expire_timeuser表是整個系統的基石所有角色都在這張表里通過role字段區分。role為1表示管理員2表示教師3表示學生。student_no字段存儲學號教師賬號也用這個字段存工號只是語義上不同。密碼字段存儲的是MD5加密后的密文不是明文。這一點答辯時候經常會問答得上來說明了解基本的密碼安全常識。course_student表是學生和課程的多對多關聯表。課程可以被多個學生選擇一個學生也可以選擇多門課程這種多對多關系在關系型數據庫里必須拆成中間表。如果沒有這張表后續做考勤記錄和統計報表都會非常麻煩。attendance_record表記錄每一次簽到的結果status字段的值域和客戶端展示的邏輯保持一致。3.3 接口設計與核心接口清單接口設計遵循RESTful風格但不過度追求純REST因為課程設計階段往往不需要那么嚴格的資源語義只要路徑清晰、職責明確就行。核心接口有以下幾組POST /api/auth/login登錄接口參數為username和password返回用戶信息和TokenGET /api/course/list獲取當前用戶的課程列表學生返回已選課程老師返回自己創建的課程GET /api/course/detail獲取課程詳情包括簽到時間、地點、經緯度信息POST /api/sign/gpsGPS定位簽到參數為courseId、latitude、longitudePOST /api/sign/scan掃碼簽到參數為二維碼內容POST /api/leave/apply學生提交請假申請GET /api/leave/list獲取請假記錄列表學生看自己的老師看待審批的POST /api/leave/approve教師審批請假所有接口統一返回JSON格式包含code、message、data三個字段。code為200表示成功401表示未授權500表示服務端異常。客戶端HttpUtil統一解析這個結構根據code決定是否彈出錯誤提示。接口定義好之后我建議用Postman或Apifox先跑一遍服務端接口確認通了再動客戶端聯調。很多人的痛苦在于客戶端一聯調就報錯結果定位了半天發現是服務端接口本身還沒寫對浪費了大量時間。先單獨驗證服務端再前后端聯調這個順序能省下至少50%的聯調時間。3.4 Token鑒權與數據安全Token鑒權的實現思路是登錄成功后服務端生成一個UUID字符串作為Token把Token和用戶ID的映射關系存到內存Map中同時設置過期時間。每個需要鑒權的請求都通過攔截器讀取Header里的Authorization字段去Map中查找對應的用戶信息找不到就返回401。這種方式對小規模系統來說簡單夠用。大規模生產環境會引入Redis存Token并考慮分布式問題但對于課堂考勤這種并發量很小的場景內存Map已經足夠。答辯的時候說到這一層老師就知道你理解了中間件在系統中的定位。密碼安全方面我在代碼里看到了一個細節登錄接口接收到密碼后先做MD5加密再和數據庫里存的密文比對。雖然MD5在現代安全標準中不夠強但對于校園局域網環境下的課程設計項目MD5加鹽已經是合格水平。如果想讓項目顯得更專業可以把MD5升級為BCrypt加密Spring Security的BCryptPasswordEncoder類可以直接引用改動量不大。4. 核心功能流程的完整實現方案4.1 登錄認證到課程列表的完整鏈路把登錄到課程列表這條主鏈路串起來講整個系統的運轉邏輯就清晰了。客戶端打開登錄頁用戶輸入學號和密碼點擊登錄按鈕后HttpUtil發起POST請求到/api/auth/login參數是用戶名和密碼。服務端Controller接收參數后調用Service層Service層查詢數據庫用戶表校驗密碼校驗通過生成Token返回。客戶端拿到返回的JSON解析出用戶信息、角色和Token把Token存到SharedPreferences然后根據角色跳轉到對應頁面。課程列表頁加載時客戶端先從本地讀取Token和用戶ID然后請求/api/course/list接口。服務端根據用戶角色做不同處理如果是學生查詢course_student表找到該學生所有選課記錄再關聯course表返回課程詳情如果是教師直接查course表返回該教師創建的課程。數據返回到客戶端后RecyclerView的Adapter把課程名稱、上課時間、地點渲染到界面上。這條鏈路雖然看起來簡單但它是整個系統的主動脈。登錄、鑒權、數據庫聯表查詢、列表渲染所有核心知識點都覆蓋了。開發時我建議先走通這條主鏈路再做其他分支功能。主鏈路通了整個項目就有了骨架后續往里填模塊會非常踏實。提示如果課程列表接口返回數據為空先別急著找客戶端問題。用Navicat打開數據庫看看course和course_student表里有沒有造好的測試數據。很多同學項目跑起來頁面空白最后發現是數據庫里一條數據都沒插入。4.2 定位簽到和掃碼簽到的完整流程GPS定位簽到的時序流程是學生點擊簽到按鈕客戶端定位獲取當前經緯度把經緯度連同courseId一起發送給服務端。服務端讀取course表里存儲的課程經緯度用Haversine公式計算兩點的球面距離距離小于100米判定為簽到成功寫入attendance_record表status設為1。如果距離超過閾值返回錯誤信息提示“不在簽到范圍內”。掃碼簽到的流程簡單一些老師在教師端點擊“生成簽到碼”按鈕服務端生成一個唯一碼并保存到course_code表同時設置過期時間比如30分鐘有效最終以二維碼形式展示在老師手機上。學生掃描二維碼后客戶端解析出碼內容并發送到服務端服務端校驗碼是否存在、是否過期、是否屬于當前這門課程校驗通過后寫入考勤記錄。這里有個細節值得注意掃碼簽到時客戶端需要把當前登錄用戶ID一起傳給服務端服務端不能只靠二維碼內容來判斷是誰在簽到。否則如果一個學生把二維碼截圖發給其他同學別人也能掃碼成功這個漏洞在答辯時被老師抓住會很尷尬。我在實現時掃碼簽到的接口同時校驗碼的有效性和當前登錄用戶是否選修了這門課程兩者都通過才算簽到成功。4.3 考勤統計與報表導出的實現思路考勤統計是教師端最實用的功能。教師進入某門課程的統計頁面服務端聚合該課程所有學生的簽到記錄返回每個學生的出勤次數、遲到次數、缺勤次數、請假次數。客戶端用柱狀圖或者餅圖展示匯總數據簡單的圖表可以用MPAndroidChart庫界面效果不錯引入成本低。如果想導出Excel報表可在服務端引入Apache POI庫。服務端根據統計數據生成Excel文件并返回給客戶端下載或者提供一個下載鏈接由瀏覽器直接訪問。我實現的版本里教師端可以按課程導出整個班級的考勤明細表字段包括學號、姓名、簽到時間、簽到狀態。這對老師來說是非常實用的功能答辯時也容易出彩。提示POI庫的版本選擇要注意和Java版本兼容。Spring Boot 2.x對應POI 4.x或5.x均可但POI 5.x要求Java 8以上如果你本地是Java 11或更高版本放心使用5.x。4.4 請假審批的流程閉環請假審批流程看起來不復雜但它是考勤系統閉環不可或缺的一環。沒有請假功能學生缺勤只能一律記為缺勤這對有正當理由缺課的學生不公平老師也不好操作。我把請假流程設計成三步學生提交、教師審批、考勤狀態更新。學生提交請假申請時客戶端將學號、課程ID、請假類型、起止時間、理由作為參數傳給服務端服務端插入leave_apply表狀態為待審批。教師端刷新請假列表看到待審批的申請后點擊通過或者駁回。如果通過服務端自動判斷本次請假是否覆蓋了該課程的上課時間如果覆蓋則在attendance_record表中生成一條狀態為3請假的記錄保證考勤統計時該學生不會被記成缺勤。這里有個容易遺漏的環節學生可能一次請假跨多天、多節課程。實現時要做時間區間與課程時間的重疊判斷不能只標記一門課程。我用一個兩層循環實現的外層遍歷請假時間段內的所有日期內層遍歷該學生的所有課程判斷課程上課時間是否落在請假區間內命中則生成對應的請假考勤記錄。5. 環境搭建、部署配置與問題排查實錄5.1 從零跑通整個項目的標準步驟拿到這套源碼后從零開始跑通全項目需要按順序操作。先說服務端環境準備安裝JDK 1.8或11、Maven 3.6、MySQL 5.7或8.0、Navicat或MySQL Workbench。準備就緒后用Navicat創建一個名為attendance_system的數據庫然后導入項目database目錄下的SQL腳本。腳本會創建全部6張數據表并插入一部分測試數據包括幾個學生賬號、教師賬號和課程記錄。接著修改application.yml里的數據庫用戶名和密碼確保和本地MySQL一致。用Maven執行mvn spring-boot:run或者在IDE里直接運行主類看到“Started ... Application”日志說明服務端啟動成功。這時用Postman測試接口比如調用登錄接口確認能返回Token。客戶端部分用Android Studio打開AndroidClient目錄。首次打開會自動下載依賴時間取決于網絡和配置。先在build.gradle里確認compileSdkVersion和targetSdkVersion建議compileSdkVersion 30targetSdkVersion 30。然后在網絡工具類里改服務端IP地址如果使用模擬器用10.0.2.2代指宿主機如果是真機要改成電腦在局域網中的IP比如192.168.1.100。改完后點擊Run選擇模擬器或真機運行。提示真機調試時手機和電腦必須處于同一WiFi網絡防火墻也要放行8080端口。Windows系統開著防火墻大概率會攔截來自手機的訪問開發時建議直接關閉防火墻或者在入站規則里放行Java進程。5.2 網絡通信相關的高頻報錯與解法聯調階段最常遇到的網絡報錯我梳理成了一張速查表報錯信息原因解決方案NetworkOnMainThreadException網絡請求寫在主線程用子線程或Handler包裝請求Cleartext HTTP traffic not permittedAndroid 9默認禁止明文HTTP在Manifest的application節點加android:usesCleartextTraffictrueConnection refused服務端沒啟動或IP端口不對確認服務端啟動成功確認IP和端口配置正確TimeoutException超時時間太短或網絡不通檢查網絡把OkHttp的connectTimeout調大Bad Request接口請求參數格式不對用Postman先測通確認參數名和類型這里面ClearText HTTP報錯是Android 9以上的新政策課堂上很多沒講到。如果你的targetSdkVersion大于28訪問HTTP明文地址就會直接拒絕必須配置usesCleartextTraffic為true或者改用HTTPS。很多同學一聯網就崩改了這個配置就好。5.3 數據庫層面的典型坑點數據庫層面的問題大多集中在SQL腳本導入失敗和中文亂碼兩類。導入失敗通常是因為腳本里的SQL語法版本和本地MySQL不兼容特別是存在DEFAULT CURRENT_TIMESTAMP這類語法時MySQL 5.x和8.x表現差異很微妙。解決方法是直接打開SQL文件復制關鍵建表語句在Navicat的查詢窗口里逐段執行精確復現問題。中文亂碼問題則出現在連接串沒有指定characterEncoding參數的時候。MySQL連接URL的末尾一定要加上useUnicodetruecharacterEncodingutf8否則寫入的中文會變成問號。注意MySQL 8.0的驅動類名改成了com.mysql.cj.jdbc.DriverURL里還建議加serverTimezoneAsia/Shanghai不然可能出現時區相關的報錯。5.4 客戶端運行與Android Studio的兼容問題Android Studio版本差異帶來的坑也不少。如果你用的是較新的Android Studio版本打開老項目的時候Gradle同步可能會失敗。常見的錯誤是Gradle版本和插件版本不匹配或者依賴倉庫訪問不到。我建議做一次極簡處理新建一個空白項目復制模塊代碼或者直接升級項目的Gradle版本到當前Android Studio默認推薦的版本。還有一個高頻問題是模擬器不顯示定位結果。Android模擬器默認位置在美國舊金山需要在模擬器的Extended Controls里手動設置經緯度坐標模擬定位否則定位簽到永遠顯示不在范圍內。這個坑位解答了很多學生問的“為什么我在模擬器上定位簽到總是失敗”的問題。真機調試則要確保定位權限和GPS開關都已打開。6. 項目改進方向與擴展思路基礎功能說完說說這套系統還能往哪些方向擴展。課程設計的評分往往看重創新點在原系統上加一兩個亮點答辯分數會明顯不一樣。一個可行的方向是加入WiFi指紋定位輔助簽到。教學樓里GPS信號差但每個教室的WiFi信號覆蓋是穩定的。可以在服務端預先采集每個教室WiFi信號的特征值簽到時客戶端上報當前掃描到的WiFi列表和信號強度服務端和指紋庫匹配落在對應教室則簽到成功。這個方案比GPS更精準也更有技術含量但實現復雜度高一些。另一個方向是地理圍欄Geofencing。Android系統原生支持Geofencing API可以在地圖上畫一個半徑100米的圓形區域學生進入區域后系統自動觸發簽到提醒不用手動點擊簽到按鈕。這個功能非常適合超大課時的課堂展示效果也好。需要引入Google Play Services庫真機調試限制較多模擬器基本不能用。從技術棧升級的角度客戶端可以逐步遷移到Kotlin和Jetpack Compose服務端可以把內存版Token換成Redis管理數據庫表可以引入分表分庫策略。但這些方向對課設來說屬于錦上添花先把現有代碼吃透能在答辯時講清楚每一行關鍵代碼的邏輯其實比堆功能重要的多。最后再分享一點個人體會。這個項目做完我對“全棧開發”這個概念有了實感——單純的Android頁面展示很容易學但當你把數據從數據庫經過服務端接口送到界面上的時候整條鏈路的每一環都會因為一個字段名不一致、一個時間格式不統一而卡住。課程設計的意義不在于功能多炫而在于你能完整地掌控從數據庫表設計到前端展示的全過程。我這套考勤系統源碼里的注釋寫得很細數據庫設計文檔里也標注了每個字段的含義和表之間的關聯關系照著源碼和文檔走一遍你收獲的不只是一份源碼而是一套完整的項目思維。如果大家在跑通代碼的過程中還有什么卡住的地方可以對照文章里整理的排查表逐一過一遍大部分問題都不是技術問題而是配置細節沒對齊。本文還有配套的精品資源點擊獲取