Android Studio:如何不使用全局静态变量通过用户ID更新SQLite数据
问题描述
作为编程和Android Studio新手,我正在为简易聊天项目实现ProfileActivity,希望用户注册登录后能通过表单更新SQLite数据库User表的行数据。
最初计划通过DatabaseHelper的updateUser方法,用user.getId()作为更新条件:
public void updateUser(User user) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_USER_NAME, user.getName()); values.put(COLUMN_USER_CITY, user.getCity()); values.put(COLUMN_USER_AGE, user.getAge()); values.put(COLUMN_USER_SEX, user.getSex()); // 更新行 db.update(TABLE_USER, values, COLUMN_USER_ID + " = ?", new String[]{ String.valueOf(user.getId()) }); db.close(); }
但始终获取到user.getId()=0,导致更新失败。后来用公共静态变量user_id实现了功能,但违反了数据封装原则。
解决方案
下面提供几种不依赖公共静态变量的实现方式:
方案1:登录时获取完整User对象并传递到ProfileActivity
步骤1:修改DatabaseHelper的登录方法,返回完整User对象
将原checkLoggedUser方法从返回布尔值改为返回User对象(登录成功返回用户实例,失败返回null):
@SuppressLint("Range") public User checkLoggedUser(String email, String password) { String[] columns = { COLUMN_USER_ID, COLUMN_USER_NAME, COLUMN_USER_EMAIL, COLUMN_USER_AGE, COLUMN_USER_CITY, COLUMN_USER_SEX }; SQLiteDatabase db = this.getReadableDatabase(); String selection = COLUMN_USER_EMAIL + " = ?" + " AND " + COLUMN_USER_PASSWORD + " = ?"; String[] selectionArgs = {email, password}; Cursor cursor = db.query(TABLE_USER, columns, selection, selectionArgs, null, null, null); User user = null; if (cursor.moveToFirst()) { user = new User(); user.setId(cursor.getInt(cursor.getColumnIndex(COLUMN_USER_ID))); user.setName(cursor.getString(cursor.getColumnIndex(COLUMN_USER_NAME))); user.setEmail(cursor.getString(cursor.getColumnIndex(COLUMN_USER_EMAIL))); user.setAge(cursor.getInt(cursor.getColumnIndex(COLUMN_USER_AGE))); user.setCity(cursor.getString(cursor.getColumnIndex(COLUMN_USER_CITY))); user.setSex(cursor.getString(cursor.getColumnIndex(COLUMN_USER_SEX))); } cursor.close(); db.close(); return user; }
步骤2:登录成功后传递User对象到ProfileActivity
假设登录页面为LoginActivity,登录验证通过时传递用户对象:
User loggedInUser = databaseHelper.checkLoggedUser(email, password); if (loggedInUser != null) { Intent intent = new Intent(LoginActivity.this, ProfileActivity.class); // 确保User类实现Serializable接口 intent.putExtra("LOGGED_IN_USER", loggedInUser); startActivity(intent); }
步骤3:在ProfileActivity中接收并使用User对象
修改ProfileActivity的initObjects方法,填充原有用户数据:
private void initObjects() { databaseHelper = new DatabaseHelper(activity); // 接收登录时传递的User对象 user = (User) getIntent().getSerializableExtra("LOGGED_IN_USER"); // 填充表单原有数据 inputName.setText(user.getName()); inputAge.setText(String.valueOf(user.getAge())); inputCity.setText(user.getCity()); inputSex.setText(user.getSex()); }
步骤4:恢复原updateUser方法
将DatabaseHelper的updateUser改回最初版本,不再依赖静态变量:
public void updateUser(User user) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_USER_NAME, user.getName()); values.put(COLUMN_USER_CITY, user.getCity()); values.put(COLUMN_USER_AGE, user.getAge()); values.put(COLUMN_USER_SEX, user.getSex()); // 使用user对象的id作为更新条件 db.update(TABLE_USER, values, COLUMN_USER_ID + " = ?", new String[]{ String.valueOf(user.getId()) }); db.close(); }
方案2:修改update方法,直接接收userId参数
若不想传递整个User对象,可让updateUser直接接收userId和更新字段:
步骤1:修改DatabaseHelper的updateUser方法
public void updateUser(int userId, String name, int age, String city, String sex) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_USER_NAME, name); values.put(COLUMN_USER_CITY, city); values.put(COLUMN_USER_AGE, age); values.put(COLUMN_USER_SEX, sex); db.update(TABLE_USER, values, COLUMN_USER_ID + " = ?", new String[]{ String.valueOf(userId) }); db.close(); }
步骤2:用SharedPreferences存储并读取userId
登录成功时存储userId:
SharedPreferences sp = getSharedPreferences("USER_INFO", MODE_PRIVATE); sp.edit().putInt("USER_ID", loggedInUserId).apply();
在ProfileActivity中读取并调用更新方法:
int userId = getSharedPreferences("USER_INFO", MODE_PRIVATE).getInt("USER_ID", -1); if (userId != -1) { String name = inputName.getText().toString().trim(); int age = Integer.parseInt(inputAge.getText().toString().trim()); String city = inputCity.getText().toString().trim(); String sex = inputSex.getText().toString().trim(); databaseHelper.updateUser(userId, name, age, city, sex); }
注意事项
- 方案1中,
User类需实现Serializable接口才能通过Intent传递:
public class User implements Serializable { // 原有字段、getter和setter方法 }
- 保持
DatabaseHelper的单一职责,仅负责数据库操作,避免持有全局状态。
内容的提问来源于stack exchange,提问作者candycandy2023
相关产品推荐
相关产品推荐

