news 2026/10/10 1:04:37

安卓图书管理系统课设:SQLite+RecyclerView实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
安卓图书管理系统课设:SQLite+RecyclerView实战

简介:这是一份基于 Android Studio 开发的完整图书管理系统项目源码,主要面向学习 Android 原生应用开发和 SQLite 数据库操作的开发者、学生或课程设计人员。项目围绕图书数据管理这一核心场景,完整覆盖新增、删除、修改、查询四类操作,并借助 SQLiteOpenHelper 与 SQLiteDatabase 完成建库、版本升级和 SQL 语句执行;除基础增删改查外,还包含图书表单录入、列表展示、按作者/出版社/关键词筛选查询等界面与逻辑设计,同时预留二维码扫码入库(如集成 Zxing)等扩展方向,能帮助读者理解从 Android 界面交互到数据库持久化的完整开发链路,也可对照学习 insert、delete、update、query、rawQuery 等数据库接口的实际用法。压缩包整体约 23.26MB,内含 Android 工程源码与相关配置文件,导入 Android Studio 后即可查看、运行和调试。目前已有 4060 人学习下载,适合作为课程设计、毕业设计或自学练手的实践素材。

1. 安卓图书管理系统:为什么说这是最值得自己敲一遍的 Android Studio 课设

又到课设季,图书馆里见到的题目里,「图书管理系统」可能是出现频率最高的一个。网上能找到的版本五花八门:有的是十年前的 Eclipse 古董工程,打开后连 project 结构都对不上;有的是纯网页后台管理系统,套了个安卓壳就说是 App。而这个标题说的安卓图书管理系统(Android Studio版本),就是要你在 Android Studio 里从零搭一个本地应用,通过 SQLite 管理图书、读者和借书还书流程,不依赖服务器,单机就能演示。它适合正在选题目的学生,也适合想用一个小项目把 Activity、RecyclerView、SQLite 串起来的入门开发者。下文我会把工程骨架、数据层、界面层到避坑记录完整走一遍,保证照着敲能跑、答辩护得住。

2. 图书管理系统的工程骨架:Android Studio 安装配置、Gradle 与分包

2.1 下载安装与三处必改配置:语言包、SDK 路径与 Gradle 版本

做这个项目的第一步不是写代码,而是把 Android Studio 装到能稳定编译的状态。常见做法是去官网下载最新稳定版,看到网上有人让你下 Android Studio 3.5 那种老版本,不用理,老版本对应旧 Gradle 插件,新建工程时模板和新版差很多。国内网络下载慢的话,就换官网国内节点或者镜像,安装包本身解压完继续在线拉 SDK 组件。

装完之后我一般先做三件小事。第一,界面设成中文。现在 Android Studio 是支持中文语言包的,在 Settings 里搜 Plugins,安装 Chinese (Simplified) Language Pack,重启就是中文界面。第二,确认 SDK 路径。Windows 上默认在%LOCALAPPDATA%\Android\Sdk,如果 C 盘吃紧,在 Settings 里把 SDK 位置改到 D 盘,能省下几个 GB。第三,Gradle 版本听 Android Studio 的,新建工程时它给你配什么就用什么。不要把工程里的 Gradle 版本手动改到新版本,也不要为了兼容老机器强制降级,和 AGP 插件版本匹配不上时,编译阶段就会冒出一堆难懂的错误。

新建工程的模板选择上,课程设计类项目直接选 Empty Views Activity,注意不是 Empty Activity,新版模板里带 Compose 的不要选,图书管理系统用传统 View 体系更顺手,后面所有代码也都在这个体系里写。

2.2 分包结构:Model、DB、Adapter、UI 各司其职

工程建好后,先别急着写界面,把包结构定下来。我一般会按三层来分,视图层只做界面展示和点击事件,数据访问层只负责 SQL 操作,模型层放纯数据类。这样做的直接好处是,答辩时老师问「数据库操作在哪写的」「界面逻辑是哪些」,你能两句话指出来;后面要换数据库或者改页面,也不用从头重写。

com.example.bookmanager/ ├── MainActivity.java // 入口,底部导航或侧边栏 ├── ui/ │ ├── BookListActivity.java // 图书列表页 │ ├── BookEditActivity.java // 新增/编辑图书页 │ ├── ReaderListActivity.java// 读者管理页 │ └── BorrowActivity.java // 借书/还书操作入口 ├── adapter/ │ ├── BookAdapter.java // 图书列表适配器 │ └── ReaderAdapter.java // 读者列表适配器 ├── db/ │ ├── DBHelper.java // 继承 SQLiteOpenHelper │ ├── BookDao.java // 图书表的增删改查 │ ├── ReaderDao.java // 读者表的增删改查 │ └── BorrowDao.java // 借阅记录的写入与更新 ├── model/ │ ├── Book.java │ ├── Reader.java │ └── BorrowRecord.java └── utils/ └── DateUtils.java // 日期格式化与逾期判断

分包不是形式主义。比如Book.java是纯 JavaBean,字段对应 book 表的列,不带任何 SQL;BookDao.java里写insert、queryAll、search方法,Activity 只调方法不写 SQL;把 SQL 都塞在 Activity 里的代码,前期快,后期维护就是灾难。真实课设里最常见的翻车现场,就是所有代码堆在 MainActivity 里,一个文件两三千行,改个布局要找半天。

2.3 Gradle 依赖配置:RecyclerView 与 Material 组件

图书管理系统用到的 AndroidX 组件不多,但要在build.gradle里提前配好,否则写到一半发现RecyclerView找不到,又要停下补依赖。

dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.9.0' implementation 'androidx.recyclerview:recyclerview:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' }

版本号以你新建工程时实际拉到的为准,上面这几个是我项目里在用的稳定组合。注意 compileSdk 版本和依赖版本要匹配:compileSdk 设成 35 却配很老的 appcompat,资源合并时会报错;如果报的是资源冲突,先把依赖版本统一往上提,不要急着删文件。Material 组件库提供SearchView、DatePickerDialog这些控件,比自己去写原生 EditText 弹窗省事得多。

3. 图书管理系统的数据层:SQLite 三张表、DAO 封装与借还书事务

3.1 表结构设计:图书、读者、借阅记录三张表怎么建

数据层是图书管理系统的命脉。这个项目的核心业务就是借书、还书,说白了是三个实体:图书、读者、借阅记录。很多新手喜欢把借阅记录做成「书名 + 读者名」两列直接塞进去,这么设计的问题在于,如果书或者读者信息改了,历史记录里存的还是旧名字,查询时还得绕。正确的做法是借阅表只存 ID,用外键去关联图书和读者。

CREATE TABLE book ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, author TEXT DEFAULT '', isbn TEXT UNIQUE, publisher TEXT DEFAULT '', price REAL DEFAULT 0.0, stock INTEGER DEFAULT 1, total INTEGER DEFAULT 1 ); CREATE TABLE reader ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, phone TEXT, reg_date TEXT DEFAULT (date('now')) ); CREATE TABLE borrow ( id INTEGER PRIMARY KEY AUTOINCREMENT, book_id INTEGER NOT NULL, reader_id INTEGER NOT NULL, borrow_date TEXT DEFAULT (date('now')), due_date TEXT NOT NULL, return_date TEXT, FOREIGN KEY (book_id) REFERENCES book(id), FOREIGN KEY (reader_id) REFERENCES reader(id) );

参数说明:stock是当前可借库存,total是馆藏总数,借出时stock减一、还书时加一,total不变,页面显示「馆藏/可借」时两个字段都有用。isbn加 UNIQUE 能防止同一本书重复录入,但注意 UNIQUE 约束的列在插入重复值时insert会返回 -1,不会主动抛异常,代码里要判断插入结果。borrow表不冗余图书名和读者名,查列表时 JOIN 两张表把名称查出来,这是规范做法,也是答辩时能加分的点。

3.2 DBHelper 与 DAO:把 SQLiteOpenHelper 封装成可复用类

接下来是数据访问层的实现。DBHelper 继承 SQLiteOpenHelper,负责数据库文件的创建和版本升级;DAO 负责具体的 SQL 操作。这里有一个容易被忽视的点:onUpgrade里直接 DROP TABLE 再重建,是课设场景图省事的写法,但批量删除老表会导致升级后数据全丢。生产环境要做的是用ALTER TABLE加列或者写迁移逻辑,这点在代码注释里我一般会写明。

public class DBHelper extends SQLiteOpenHelper { private static final String DB_NAME = "book_manager.db"; private static final int DB_VERSION = 1; public DBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK_TABLE); db.execSQL(CREATE_READER_TABLE); db.execSQL(CREATE_BORROW_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 课设阶段直接重建最省事,生产环境务必改成逐版本迁移 db.execSQL("DROP TABLE IF EXISTS borrow"); db.execSQL("DROP TABLE IF EXISTS reader"); db.execSQL("DROP TABLE IF EXISTS book"); onCreate(db); } }

BookDao 里做图书的增删改查。这里我建议用db.query而不是手拼 SQL 字符串,query方法的 selectionArgs 会帮你做参数绑定。图书搜索时如果用户输入的关键字里带了单引号,手拼字符串直接 SQL 语法错误,用参数绑定就完全没这个问题。

public class BookDao { private final DBHelper helper; public BookDao(Context context) { helper = new DBHelper(context); } public long insert(Book book) { SQLiteDatabase db = helper.getWritableDatabase(); ContentValues cv = new ContentValues(); cv.put("title", book.title); cv.put("author", book.author); cv.put("isbn", book.isbn); cv.put("publisher", book.publisher); cv.put("price", book.price); cv.put("stock", book.stock); cv.put("total", book.total); long rowId = db.insert("book", null, cv); db.close(); return rowId; } public List<Book> search(String keyword) { SQLiteDatabase db = helper.getReadableDatabase(); Cursor cursor = db.query("book", null, "title LIKE ? OR author LIKE ?", new String[]{"%" + keyword + "%", "%" + keyword + "%"}, null, null, "id DESC"); List<Book> list = new ArrayList<>(); while (cursor.moveToNext()) { Book b = new Book(); b.id = cursor.getLong(cursor.getColumnIndexOrThrow("id")); b.title = cursor.getString(cursor.getColumnIndexOrThrow("title")); b.author = cursor.getString(cursor.getColumnIndexOrThrow("author")); b.stock = cursor.getInt(cursor.getColumnIndexOrThrow("stock")); list.add(b); } cursor.close(); db.close(); return list; } }

两点说明。第一,getWritableDatabase()和getReadableDatabase()在绝大多数场景下没有区别,磁盘满时前者会抛异常,后者会尝试只读打开,课程设计不用纠结,写操作用前者、读操作用后者就行。第二,Cursor遍历完一定要close(),数据库连接用完也建议close()。有些教材说 SQLiteOpenHelper 内部有连接缓存,关不关都一样,但实测里不关 Cursor 在反复搜索时会出现CursorWindow内存泄漏,Android Studio 的 Memory Profiler 里能看到明显上涨。

3.3 借书还书的事务:库存不一致是这么来的

借书流程看起来简单,但最容易出问题的地方在「先检查再扣减」的中间状态。如果不加事务,借书操作做到一半时异常退出,就会出现「借阅记录插进去了、库存没减」或者反过来库存减了、没有借阅记录。真实项目里这是不能接受的,解决方式就是 SQLite 事务。

public boolean borrow(long bookId, long readerId) { SQLiteDatabase db = helper.getWritableDatabase(); db.beginTransaction(); try { // 1. 检查库存 Cursor cursor = db.rawQuery("SELECT stock FROM book WHERE id = ?", new String[]{String.valueOf(bookId)}); int stock = 0; if (cursor.moveToFirst()) { stock = cursor.getInt(0); } cursor.close(); if (stock <= 0) { return false; } // 2. 检查该读者是否还有未还的这本书 Cursor borrowCursor = db.rawQuery( "SELECT COUNT(*) FROM borrow WHERE book_id = ? AND reader_id = ? AND return_date IS NULL", new String[]{String.valueOf(bookId), String.valueOf(readerId)}); boolean exists = borrowCursor.moveToFirst() && borrowCursor.getInt(0) > 0; borrowCursor.close(); if (exists) { return false; } // 3. 插入借阅记录,默认借期 30 天 ContentValues cv = new ContentValues(); cv.put("book_id", bookId); cv.put("reader_id", readerId); cv.put("due_date", DateUtils.plusDays(DateUtils.today(), 30)); db.insert("borrow", null, cv); // 4. 扣减库存 db.execSQL("UPDATE book SET stock = stock - 1 WHERE id = ?", new Object[]{bookId}); db.setTransactionSuccessful(); return true; } catch (Exception e) { Log.e("BorrowDao", "borrow failed", e); return false; } finally { db.endTransaction(); } }

事务的关键逻辑在beginTransaction()到endTransaction()之间:只有调用了setTransactionSuccessful(),事务才会提交;任意一步抛异常,endTransaction()都会回滚整个事务。我前面写的第 2 步很多人会漏掉,结果就是同一个读者能反复借同一本书,把库存借成负数。还书操作是对称的,更新return_date后stock + 1,也可以用同一个事务包起来。

4. 图书管理系统的界面层:列表、借还书操作与搜索 UI

4.1 图书列表页:RecyclerView 适配器与点击事件

旧教程里还在教 ListView,现在新建的 Android Studio 工程默认带 Material 组件,RecyclerView 已经是事实标准,性能和数据绑定方式都比 ListView 清晰。图书列表页的结构是这样:一个 RecyclerView 显示卡片,每张卡片上有书名、作者、库存状态,右边一个「借书」按钮,长按卡片弹还书或删除菜单。

public class BookAdapter extends RecyclerView.Adapter<BookAdapter.VH> { private final List<Book> data = new ArrayList<>(); public void submit(List<Book> list) { data.clear(); data.addAll(list); notifyDataSetChanged(); } @Override public VH onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_book, parent, false); return new VH(view); } @Override public void onBindViewHolder(VH holder, int position) { Book book = data.get(position); holder.title.setText(book.title); holder.author.setText(book.author + " / 库存 " + book.stock); holder.status.setText(book.stock > 0 ? "可借" : "已借出"); holder.status.setTextColor(book.stock > 0 ? Color.GREEN : Color.RED); holder.itemView.setOnClickListener(v -> Toast.makeText(holder.itemView.getContext(), book.title + " 的 ISBN 是 " + book.isbn, Toast.LENGTH_SHORT).show()); } @Override public int getItemCount() { return data.size(); } static class VH extends RecyclerView.ViewHolder { TextView title, author, status; VH(View itemView) { super(itemView); title = itemView.findViewById(R.id.tv_title); author = itemView.findViewById(R.id.tv_author); status = itemView.findViewById(R.id.tv_status); } } }

逻辑说明:onCreateViewHolder里 inflate 时 parent 参数必须传,否则 item 根布局的layout_width和layout_height会失效,这是 RecyclerView 初学者最容易踩的玄学坑之一。状态字段在onBindViewHolder里每次都要重新赋值,因为 ViewHolder 会复用,不复位就会出现「上面显示可借、下面显示已借出」的错乱。刷新列表用submit()方法做全量替换,简单直接,等数据量大了再考虑ListAdapter + DiffUtil的增量更新方案。

4.2 借书与还书操作:弹窗选读者、列表即时刷新

图书列表只是展示层,真正的业务逻辑集中在借书和还书这两个动作上。借书的交互流程建议这样做:用户点「借书」按钮,弹出一个 AlertDialog,里面用 Spinner 列出当前所有读者,选完确认后调用BorrowDao.borrow();成功就刷新列表,失败弹 Toast 说明原因。

public void onBorrowClick(Book book) { List<Reader> readers = readerDao.queryAll(); if (readers.isEmpty()) { Toast.makeText(this, "请先在读者管理页添加读者", Toast.LENGTH_SHORT).show(); return; } ArrayAdapter<Reader> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, readers); Spinner spinner = new Spinner(this); spinner.setAdapter(adapter); new AlertDialog.Builder(this) .setTitle("选择借书人:" + book.title) .setView(spinner) .setPositiveButton("确认借出", (dialog, which) -> { Reader selected = (Reader) spinner.getSelectedItem(); boolean ok = borrowDao.borrow(book.id, selected.id); if (ok) { Toast.makeText(this, "借出成功", Toast.LENGTH_SHORT).show(); refreshList(); } else { Toast.makeText(this, "库存不足或该读者已借此书", Toast.LENGTH_SHORT).show(); } }) .setNegativeButton("取消", null) .show(); }

注意borrowDao.borrow返回的布尔值只能说明成没成功,具体是库存不足还是重复借阅,从返回值里看不出来,排查时需要看 DAO 里的日志。如果想让提示更细,可以让 borrow 方法返回一个错误码枚举,比如OK、OUT_OF_STOCK、DUPLICATE_BORROW,界面按码提示,这样演示时不会显得太生硬。

4.3 搜索、日期与 UI 细节:进度条和资源命名

搜索功能是这个系统的门面,演示时最容易出效果。常见做法是用 SearchView 放在列表页顶部,监听文本变化实时调用 DAO 的search方法。如果不想引入 SearchView 的样式适配,一个 EditText 加 TextWatcher 也够用。

editText.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { bookAdapter.submit(bookDao.search(s.toString().trim())); } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { } });

日期逻辑上,借书时的borrow_date默认当天,due_date默认 30 天后;还书时只需写入return_date,逾期判断放在列表的 getter 里:return_date == null && due_date < today就是逾期。日期比较一律用yyyy-MM-dd字符串形式,因为 SQLite 的 date 函数输出就是这个格式,字符串按字典序比较就等于按日期比较,省去 Date 对象转换的麻烦。

界面细节上还有两个点值得提。一是加载数据时给页面加一个 ProgressBar,Activity 里setVisibility(View.VISIBLE),数据加载完再GONE,虽然本地 SQLite 查询很快基本闪一下,但演示时不会因为列表空白显得卡顿。二是资源文件命名,drawable 和 layout 里的文件不要用泛化名字,比如book.xml、item.xml;一个工程里出现同名文件,Android Studio 会直接报资源重复错误,到时候删文件都找不到哪个被引用了。

5. 避坑指南:安卓图书管理 App 编译与运行的 5 个翻车现场

5.1 Android 12+ 闪退:Activity 少了 exported 声明

现象:工程 targetSdk 设置为 31 以上,装到 Android 12 的真机上,应用一启动就闪退,Logcat 报SecurityException: Activity is not exported。

原因:Android 12 起,凡是带 intent-filter 的 Activity 必须在 Manifest 里显式声明android:exported。新建工程模板自动带这个属性,但很多人抄旧代码时少了这一行。

解决:给主 Activity 加上android:exported="true"。如果应用里有其他 Activity 用了隐式 Intent 启动,同样要补声明;不对外暴露的 Activity 写false反而更安全。

5.2 编译报资源重复错误:R 类生成失败

现象:Build 报Duplicated resources或者说R类里找不到某个id,查看R.java时发现有的资源被覆盖了。

原因:res 目录下出现了两个同名布局或两个同名 drawable 文件。常见来源是把同一个book_item.xml在多个模块里各复制了一份,或者图片资源同时放在drawable和mipmap里用同一个名字。

解决:在 Android Studio 里打开 View > Tool Windows > Resource Manager,按资源名搜索查重;删掉多余文件后 Build > Clean Project 再重新编译。命名约定上,item 类布局用item_book.xml这种前缀区分,背景图用bg_前缀,图标用ic_前缀,从根上避免重名。

5.3 RecyclerView 列表数据错乱

现象:列表滚动几下后,书名的位置对不上,有的卡片显示「库存 0」但状态却是「可借」。

原因:ViewHolder 机制下 item 会被复用,onBindViewHolder里没给所有字段重新赋值,导致复用时残留上一行的数据。

解决:在onBindViewHolder里把每个会变动的字段都赋值一遍,内容为空时也显式setText("");如果字段值依赖库存数,不要在 ViewHolder 里做缓存,每次绑定都按当前数据重新计算。

5.4 数据库文件在文件管理器里看不到

现象:运行后想导出book_manager.db备份,在手机文件管理器里怎么也找不到这个文件,怀疑数据没写进去。

原因:SQLiteOpenHelper 默认把数据库放在/data/data/包名/databases/目录,普通文件管理器没有权限访问。网上看到的/storage/emulated/0/android/data/...这类路径是 Android 11 分区存储后的应用专属外部目录,跟内置数据库是两个位置,不要混淆。

解决:Android Studio 自带 App Inspection 工具,运行 App 后在工具窗口打开 Database Inspector 就能看到表和数据;或者用adb exec-out run-as 包名 cat databases/book_manager.db > book_manager.db把数据库导出到电脑。用真机调试时,确保手机和电脑在同一网络,开启 USB 调试后选「文件传输」模式,不然 adb devices 列表永远是空的。

5.5 真机调试连不上 ADB,或迁移后 Gradle 不停报错

现象:手机开了开发者选项和 USB 调试,但adb devices显示找不到设备;另一类情况是工程从旧电脑迁移到新 Android Studio 后,Gradle 同步时一直报版本不匹配。

原因:前者通常是 USB 连接模式停在「仅充电」,或者驱动没对;后者是旧工程的 AGP 版本和当前 Android Studio 自带的 JDK 不兼容,最常见的就是 Gradle 版本低、AGP 版本高,直接冲突。

解决:先切换 USB 模式为「文件传输」再试;还不行就adb kill-server后重新adb start-server,重启 adb 服务能解决一半玄学问题。Gradle 报错时,用 Android Studio 提示的 Fix 按钮自动调整版本,或者把工程根目录build.gradle里的 AGP 版本改成当前 Studio 默认创建的版本,不要手动指定一个网上教程里的老版本号。

6. 一点进阶:从能运行到不心虚的安卓图书管理工程习惯

课程设计交到我手里,我的习惯是先把验证流程固定下来,再谈代码好看不好看。数据库这块别只靠眼睛看,Android Studio 的 App Inspection 打开 Database Inspector,直接查看借书后库存有没有减、还书时间有没有更新,比反复 Log 打印 Cursor 数据快得多。想更正式一点,可以在 androidTest 目录里写一个测试类,直接调 BorrowDao 插入一条借阅记录再查询断言,Android 里跑起来也就几十秒。

导出备份数据时,如果想把数据库或 CSV 存到公共存储目录,注意 Android 7.0 以后用 FileProvider,生成的是content://开头的 URI,直接传file://路径会抛FileUriExposedException。网上的老博客还推荐用 Apache HttpClient 联网,那个类在 Android 6.0 起就从系统里移除了,照抄会运行期崩溃,这也是我建议把图书管理系统做成纯本地的原因之一。

代码组织上有个小技巧:开发时先把功能写在一个方法里,跑通后选中代码块按 Ctrl+Alt+M(Mac 上是 Option+Command+M)抽取成独立方法,再边看边改优化。这比对着架构图从零写更符合实际节奏,我也一直这么干。至于要不要把 SQLiteOpenHelper 换成 Room,我的看法是:如果你已经能熟练写 DBHelper,可以试试 Room 的编译期 SQL 校验,但如果是为了赶完课设,没必要为引入 Room 去配 kapt/ksp 注解处理器,那又是一串新的坑。

最后说一个血泪经验:课程设计交付前,一定找一台干净的真机装一次,从头点一遍借书、还书、搜索的完整流程再交,别只在模拟器上跑通就完事。模拟器里的文件路径、定位权限和真机差异比你想的大。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 1:04:21

PCA9422+PIC24FV32KA304构建主动式低功耗电源管理系统

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

作者头像 李华
网站建设 2026/10/10 1:03:40

高性能嵌入式系统电源管理:DVFS协同与多轨时序设计

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

作者头像 李华
网站建设 2026/10/10 1:03:11

STM32L021K4与PCA9422低功耗电源管理设计实战

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

作者头像 李华
网站建设 2026/10/10 1:02:27

SQLite在.NET中的32位与64位共存配置与避坑指南

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

作者头像 李华
网站建设 2026/10/10 1:02:12

Transformer长序列预测:代码选型与调参避坑指南

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

作者头像 李华
网站建设 2026/10/10 1:01:02

热轧带钢表面缺陷检测:工业级数据集与产线鲁棒性实践指南

简介&#xff1a;本资源是面向工业视觉、机器学习与智能制造领域研究者及工程师的热轧带钢表面缺陷图像数据集&#xff0c;专用于缺陷检测算法研发、模型训练与工业质检系统验证。压缩包共2000个文件&#xff0c;含1800张JPG格式原始缺陷图像&#xff08;覆盖crazing、inclusio…

作者头像 李华