
简介面向安卓初学者与需要快速验证登录注册原型的开发者这份资源围绕 Basic4AndroidB4A连接 MySQL 数据库展开覆盖数据库连接、登录查询、注册插入与安全防护等关键环节帮助读者理解如何在 B4A 项目中完成用户账户体系的搭建。压缩包共 53 个文件约 1.84MB包含 29 个 class、8 个 java、3 个 xml 及 3 个 bas、3 个 bal 等类型既有 B4A 源码与布局文件也附带 apk 与 dex 等可运行产物便于对照学习界面设计与数据库交互逻辑。资源已有 714 人学习下载适合作为 B4A 与 MySQL 联调的入门参考读者可从中获取连接参数配置、SQL 语句构造、密码哈希与 SQL 注入防护等实践思路并借助现成工程结构快速复现登录注册流程。1. 从一次“登录按钮点了没反应”说起去年帮朋友看一个安卓小工具界面就两个输入框加一个按钮点登录死活没反应。翻到源码才发现他用 B4A 写界面数据库却放在远端 MySQL中间那层连接压根没打通——B4A 本身不直接带 MySQL 驱动得靠 JDBC 桥接。这个项目解决的正是这件事用 B4ABasic4android做安卓端登录注册界面通过 JDBC 连远端 MySQL 完成账号校验与写入。适合谁手上有一台能跑 MySQL 的服务器、想用 Basic 语法快速搓出带真实后端的小 App、又不想啃 Android 原生 Java 的开发者。它不炫技但把“安卓端 → 网络 → 数据库”这条链路讲透了跑通一次后面加任何业务表都是照葫芦画瓢。2. 项目定位与技术选型为什么是 B4A JDBC MySQL2.1 这套组合到底在解决什么问题移动端连数据库正规做法是 App 调 HTTP 接口、接口再访问数据库中间隔一层服务端。但这个项目的场景更“直给”小团队、内部工具、教学演示没有独立后端服务希望安卓端直接和 MySQL 对话。B4A 的语法接近 VB事件驱动写起来快一个按钮的点击事件几行就能挂上MySQL 又是最常见的关系库建表、写 SQL 门槛低。两者之间缺的那座桥就是 JDBC。B4A 提供了JdbcSQL这类封装库社区常见做法是引入 JDBC 驱动 jar 并配置连接参数让 Basic 代码能像调本地方法一样执行SELECT、INSERT。所以这个项目的技术栈可以拆成三层表现层是 B4A 的 Activity 与布局文件逻辑层是按钮事件里的校验与 SQL 拼装数据层是远端 MySQL 的账号表。理解这三层后面看代码就不会迷路。需要提前说清楚一个现实安卓端直连数据库意味着数据库地址、账号、密码会出现在客户端。这在内部工具或学习场景能接受但对外发布的 App 千万别这么干。我一般会把它定位成“原型验证 内网工具”真要上线还是得在中间加一层接口。这个判断不影响你学这套代码反而能帮你决定改造方向。2.2 目录结构与关键文件清单B4A 项目的文件组织比较固定拿到源码包先认这几个位置能省不少找文件的时间。下面这张表是我拆这类项目时习惯先扫一遍的清单文件/目录作用改造时关注点Main.bas主 Activity 逻辑登录注册事件都在这事件名、SQL 语句、连接参数Main.bal布局文件输入框与按钮的声明控件 ID 要和代码里一致Starter.bas服务模块常放全局初始化连接是否在这里建立Files/资源目录驱动 jar 常放这jar 是否随包打包Manifest权限声明是否开了网络权限B4A 的布局和代码是分离的Main.bal里拖出来的每个控件都有个名字代码里靠这个名字取值和设值。新手最常见的翻车就是改了布局里的控件名代码里没同步运行时直接报找不到控件。所以拿到项目第一件事是把布局文件和.bas里的控件引用对一遍心里有数再动手。2.3 连接参数怎么配、配在哪连接 MySQL 的核心是几个参数主机地址、端口默认 3306、数据库名、用户名、密码。这些在 B4A 里通常集中写在一处方便改。常见做法是定义一个初始化方法把连接串拼好再交给 JDBC 初始化数据库连接参数集中管理便于切换环境 Sub InitDB Dim host As String 192.168.1.100 MySQL 服务器地址 Dim port As Int 3306 默认端口 Dim dbName As String appdb 目标数据库 Dim user As String appuser 数据库账号 Dim pwd As String your_password 数据库密码 拼接 JDBC 连接串注意时区与字符集参数 Dim url As String jdbc:mysql:// host : port / dbName ?useUnicodetruecharacterEncodingutf8 加载驱动并建立连接连接对象存全局变量复用 sql1.Initialize(url, user, pwd) End Sub这段代码的逻辑很直白把散落的连接信息收拢成变量拼成 JDBC 认识的 URL再交给JdbcSQL的Initialize。参数说明上characterEncodingutf8不能省否则中文昵称写进库会变问号useUnicodetrue配合它一起用。主机地址填内网 IP 或公网 IP 都行但要注意 MySQL 默认只允许本地连接远端访问得在数据库侧授权对应账号从该 IP 登录这一步不做代码写得再对也是连接超时。提示连接对象建议在应用启动时初始化一次并复用每次点击都新建连接会拖慢响应还容易把连接数打满。3. 核心模块拆解登录与注册的完整链路3.1 登录事件从取值到校验再到查询登录按钮的点击事件是整个项目的主干。它要做四件事取输入框的值、做非空校验、拼 SQL 查库、根据结果给反馈。下面这段是典型写法 登录按钮点击事件 Sub btnLogin_Click Dim u As String edtUser.Text.Trim 取用户名并去空格 Dim p As String edtPwd.Text.Trim 取密码 前端非空校验避免空查询 If u Or p Then ToastMessageShow(账号或密码不能为空, False) Return End If 参数化查询防止 SQL 注入 Dim cur As ResultSet sql1.ExecQuery2(SELECT id FROM users WHERE username ? AND password ?, Array As String(u, p)) If cur.NextRow Then ToastMessageShow(登录成功, False) 记录当前用户跳转主界面 currentUser u StartActivity(MainPage) Else ToastMessageShow(账号或密码错误, False) End If cur.Close End Sub逐段看edtUser.Text.Trim取控件文本并去掉首尾空格用户手滑多打个空格是常事不 Trim 就会出现“明明密码对却登不上”的玄学问题。非空校验放在查询前省一次无意义的数据库往返。关键在ExecQuery2这个带参数的方法——它用?占位把用户输入作为参数传入而不是字符串拼接。这一点必须坚持拼接写法遇到带引号的密码直接语法错误更别说注入风险。cur.NextRow判断有没有查到记录查到就说明账号密码匹配存下当前用户再跳转。参数说明上Array As String(u, p)的顺序要和 SQL 里?的顺序严格对应反了就是拿密码当用户名查结果永远是空。ResultSet用完记得Close虽然小项目不关也不一定立刻出问题但连接泄漏积累起来迟早会遇到“连不上数据库”的黑匣子时刻。3.2 注册事件插入前的重复校验注册比登录多一步写库前得确认用户名没被占用。逻辑顺序是“查重 → 插入 → 反馈”顺序反了会插出重复账号。 注册按钮点击事件 Sub btnRegister_Click Dim u As String edtUser.Text.Trim Dim p As String edtPwd.Text.Trim If u Or p Then ToastMessageShow(请填写完整信息, False) Return End If 先查用户名是否已存在 Dim chk As ResultSet sql1.ExecQuery2(SELECT id FROM users WHERE username ?, Array As String(u)) If chk.NextRow Then ToastMessageShow(该用户名已被注册, False) chk.Close Return End If chk.Close 不存在则插入新记录 sql1.ExecNonQuery2(INSERT INTO users (username, password) VALUES (?, ?), Array As String(u, p)) ToastMessageShow(注册成功请登录, False) End Sub这里用的是ExecNonQuery2因为它不返回结果集只执行写入。查重和插入之间理论上存在极短的并发窗口两个人同时注册同一用户名可能都通过查重但小工具场景基本遇不到真要严谨给username字段加唯一索引让数据库兜底插入失败时捕获异常提示即可。这也是我后来养成的一个习惯前端校验管体验数据库约束管正确性两层都别省。3.3 账号表结构与字段设计代码跑得通前提是表建对了。这个项目对应的账号表结构不复杂但几个字段的类型和约束值得说清楚CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, -- 自增主键 username VARCHAR(50) NOT NULL UNIQUE, -- 用户名唯一防重复注册 password VARCHAR(100) NOT NULL, -- 密码字段 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 注册时间 );username加UNIQUE是给注册查重兜底的关键前面说的并发窗口就靠它挡住。password长度给到 100是因为真实项目里密码不该明文存后面改造会提到哈希后长度会变长提前留余量省得改表。created_at用默认时间戳插入时不用手动传省一个参数也少一处出错点。字符集在建库时选utf8mb4能兼容更多字符比utf8更稳。3.4 网络权限与驱动打包代码逻辑都对运行时却连不上八成是权限或驱动没配好。B4A 项目要在 Manifest 里声明网络权限否则系统直接拦掉连接请求。常见做法是在项目属性的权限勾选里加上网络访问等价于安卓原生的INTERNET权限。另外 JDBC 驱动 jar 要放进Files目录并随包打包漏了它运行时会报找不到驱动类错误信息往往很含糊新手容易卡在这。注意驱动 jar 的版本要和 MySQL 服务端大致匹配版本差太远可能出现握手失败或认证方式不兼容报错通常指向连接阶段而非 SQL 阶段排查时先看连接日志。4. 避坑与排查那些让我返工的细节4.1 连接超时但 SQL 没问题现象是点击登录后转圈很久最后提示连接失败。原因多半是数据库侧没放行远端 IP或者服务器防火墙没开 3306 端口。解决分两步先在数据库里确认账号的登录主机权限包含客户端出口 IP再检查服务器安全组和防火墙规则。我一般会先用同一台机器上的命令行客户端连一次命令行能通、App 不通问题就在 App 侧的连接串或驱动两边都不通就是网络和授权。4.2 中文写入变问号现象是注册时昵称或用户名含中文存进库变成???。原因是连接串没带字符集参数或者表本身字符集不对。解决是把连接串补上useUnicodetruecharacterEncodingutf8同时确认建库建表用的是utf8mb4。两处都对齐中文才正常。这个坑我踩过不止一次后来养成习惯新建任何连接串字符集参数先写上再说。4.3 控件名对不上导致崩溃现象是界面能显示一点按钮就闪退或报空引用。原因是布局文件里改了控件 ID.bas代码里还在用旧名字取到的是空对象。解决是把Main.bal里的控件声明和代码里的引用逐个对照改一处同步一处。B4A 不像有些框架会在编译期强校验这类错误常常拖到运行时才暴露。4.4 密码明文存储的隐患现象倒不是报错而是安全意识上的坑账号表里密码是明文一旦库被看到所有账号直接泄露。原因是最初为了演示省事。解决是注册时对密码做哈希再存登录时把输入哈希后比对。哈希算法选常见的带盐方案即可改造量不大但价值很高第 5 章会给出具体思路。4.5 连接未关闭导致后续请求失败现象是用一阵子后所有操作都超时重启 App 又好了。原因是每次查询的ResultSet或连接没关连接数被耗尽。解决是养成“用完即关”的习惯ResultSet查完Close异常分支里也别漏。小项目连接数上限低泄漏几次就撑不住了。5. 二次开发把演示代码改成能用的东西5.1 先补安全再谈功能这套代码最该改的是密码处理。明文存储和明文比对在任何稍微认真一点的场景都不能留。改造思路是注册时对密码做哈希登录时对输入做同样哈希再比对数据库里只存哈希值。下面是一个示意性的处理函数具体哈希库按 B4A 可用的封装来选 对密码做哈希注册与登录共用同一逻辑 Sub HashPwd(raw As String) As String 常见做法是加固定盐再哈希盐值单独配置 Dim salt As String app_salt_2024 调用可用的哈希封装输出十六进制字符串 Return SHA256(raw salt) End Sub改造时把注册的插入语句改成存HashPwd(p)登录的查询条件也换成哈希后的值。注意表里password字段长度要够哈希串比明文长。盐值别写死在客户端对外发布内网工具可以接受对外就得挪到服务端。这一步做完即使库被看到攻击者也拿不到原始密码。5.2 把直连改成接口调用的过渡方案如果这个项目要往正式产品走直连数据库必须换掉。过渡方案不复杂在服务器上放一个简单的 HTTP 接口接收账号密码参数内部查库返回结果App 端把 JDBC 调用换成网络请求。B4A 有网络请求的封装改起来主要是替换事件里的那几行 SQL 调用界面和校验逻辑基本不动。这样数据库地址和账号就不会出现在客户端安全性上一个台阶。我一般会先保留直连版本作为调试对照接口版本跑通后再切过去出问题能快速定位是哪一层。5.3 验证改造是否成功的检查清单改完别急着说“应该没问题了”按下面几步走一遍更踏实。第一用新账号注册确认库里存的是哈希不是明文第二用正确密码登录成功、错误密码登录失败第三故意输入带引号的密码确认不会报 SQL 语法错误第四连续操作十几次确认没有连接耗尽第五换一台机器连同一个库确认授权范围符合预期。这几步覆盖了安全、正确性、稳定性三个维度走完心里才有底。验证项预期结果不通过时先看哪注册后查库密码为哈希串插入语句是否用了哈希函数错误密码登录提示失败查询条件是否也做了哈希特殊字符密码不报语法错是否仍用参数化查询连续操作无超时ResultSet 与连接是否关闭5.4 一个我反复用的习惯这套项目拆下来最大的教训不是某行代码写错而是“演示能跑”和“能用”之间隔着安全与健壮性两道坎。从那以后我每次拿到这类直连数据库的示例都强制先走一遍密码哈希和参数化查询的检查再谈加功能。因为功能可以慢慢补数据泄露和注入漏洞一旦上线后悔药没处买。希望这份拆解能帮你少走几步弯路把这份源码真正跑成自己项目里的第一块砖。本文还有配套的精品资源点击获取