Java新手求助:WiFi采集APP数据上报重复单一WiFi信息问题
兄弟,我刚看了你的问题,这情况我当初刚做Android WiFi采集的时候也踩过坑!咱们先搞定重复数据的问题,再一步步实现全量上报MySQL的功能。
一、解决上报重复WiFi数据的问题
你遇到的上报时始终固定某一组数据的问题,90%的概率是因为你在循环遍历WiFi列表的时候,复用了同一个对象来存储每一条WiFi的信息,没有每次创建新的实例。因为Java里对象是引用传递,最后所有的条目都会指向同一个对象,自然就都是最后一条的数据了。
错误示例(大概率你现在的写法)
// 错误:在循环外创建对象,复用同一个引用 WifiInfoBean wifiBean = new WifiInfoBean(); List<WifiInfoBean> wifiList = new ArrayList<>(); for (ScanResult result : scanResults) { wifiBean.setSsid(result.SSID); wifiBean.setBssid(result.BSSID); wifiBean.setRssi(result.level); wifiBean.setTimestamp(System.currentTimeMillis()); wifiList.add(wifiBean); } // 上报wifiList的时候,里面所有元素都是同一个对象,数据全是最后一条的
修正后的正确写法
把对象创建放到循环内部,每次遍历都生成新的实例:
List<WifiInfoBean> wifiList = new ArrayList<>(); for (ScanResult result : scanResults) { // 关键:每次循环都新建一个对象,避免引用复用 WifiInfoBean wifiBean = new WifiInfoBean(); wifiBean.setSsid(result.SSID); wifiBean.setBssid(result.BSSID); wifiBean.setRssi(result.level); wifiBean.setTimestamp(System.currentTimeMillis()); wifiList.add(wifiBean); } // 现在wifiList里的每个元素都是独立的对象,数据不会重复了
二、实现全量WiFi数据上报MySQL数据库
接下来咱们把采集到的所有WiFi数据批量插入到MySQL,推荐用JDBC批量插入(适合新手理解基础逻辑),如果后续项目复杂了可以换成MyBatis的批量操作。
1. 准备MySQL表结构
先在数据库里建一张存储WiFi信息的表:
CREATE TABLE wifi_collect ( id INT AUTO_INCREMENT PRIMARY KEY, ssid VARCHAR(100) NOT NULL, bssid VARCHAR(50) NOT NULL, rssi INT NOT NULL, collect_time BIGINT NOT NULL, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
2. JDBC批量插入代码实现
注意要开启批量提交,避免每条数据都单独连接数据库,提升效率:
public void batchInsertWifiData(List<WifiInfoBean> wifiList) { String url = "jdbc:mysql://你的数据库地址:3306/数据库名?useUnicode=true&characterEncoding=utf8&useSSL=false"; String username = "你的数据库用户名"; String password = "你的数据库密码"; String sql = "INSERT INTO wifi_collect (ssid, bssid, rssi, collect_time) VALUES (?, ?, ?, ?)"; try (Connection conn = DriverManager.getConnection(url, username, password); PreparedStatement pstmt = conn.prepareStatement(sql)) { // 关闭自动提交,开启批量模式 conn.setAutoCommit(false); for (WifiInfoBean bean : wifiList) { pstmt.setString(1, bean.getSsid()); pstmt.setString(2, bean.getBssid()); pstmt.setInt(3, bean.getRssi()); pstmt.setLong(4, bean.getTimestamp()); // 添加到批量队列 pstmt.addBatch(); } // 执行批量插入 int[] counts = pstmt.executeBatch(); // 提交事务 conn.commit(); System.out.println("成功插入 " + counts.length + " 条WiFi数据"); } catch (SQLException e) { e.printStackTrace(); // 出错回滚事务 try { if (conn != null) conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } }
3. 新手必看注意事项
- 记得在项目里添加MySQL驱动依赖(比如
mysql-connector-java:8.0.33) - 绝对不要在Android主线程里执行数据库操作,一定要放到子线程或者用
AsyncTask、协程等异步框架,避免ANR(应用无响应) - 如果后续采集的数据量很大,可以把批量插入拆分成小批次(比如每50条提交一次),避免内存溢出
内容的提问来源于stack exchange,提问作者Joe Hutchinson
相关产品推荐
相关产品推荐

