Android学生注册系统中Singleton类flag返回null的问题如何解决?
问题根因
你遇到的问题本质是Firestore数据库操作是异步执行的:
- 调用
ogrenciyiKontrolEt.OGR_KONTROL()后,数据库请求会在后台线程执行,不会阻塞当前主线程 - 你紧接着直接调用
singleton.getflag()的时候,数据库的onSuccess回调还没触发,自然拿不到被修改后的flag值
修复方案
方案1:用回调接口替代Singleton全局变量(推荐)
这种方式更符合异步逻辑,也避免Singleton全局状态带来的脏数据问题:
- 先定义回调接口
public interface OnStudentCheckListener { void onCheckResult(boolean isDuplicate); }
- 修改
OgrenciyiKontrolEt类,添加回调参数
public class OgrenciyiKontrolEt { protected String ogrenci_no; protected FirebaseFirestore firebaseFirestoreDb = FirebaseFirestore.getInstance(); public Context context; private OnStudentCheckListener listener; // 构造方法新增回调参数 public OgrenciyiKontrolEt(String ogr_no, Context context, OnStudentCheckListener listener){ this.ogrenci_no = ogr_no; this.context = context; this.listener = listener; } public void OGR_KONTROL(){ firebaseFirestoreDb.collection("Students") .get() .addOnSuccessListener(queryDocumentSnapshots -> { boolean isDuplicate = false; for(DocumentSnapshot snapshot: queryDocumentSnapshots.getDocuments() ) { String firestore_ogr_no = snapshot.getString("number"); if(ogrenci_no.equals(firestore_ogr_no)) { isDuplicate = true; break; // 找到重复就跳出循环,没必要继续遍历 } } // 把结果回调给调用方 listener.onCheckResult(isDuplicate); }) .addOnFailureListener(e -> { Toast.makeText(context,"Bir hata ile karşılaşıldı.",Toast.LENGTH_LONG).show(); listener.onCheckResult(false); // 出错默认不拦截,可根据业务调整 }); } }
- 修改Activity中的调用逻辑,把后续操作放到回调里执行
// 省略前面非空校验的代码 else{ // 初始化校验类的时候传入回调 ogrenciyiKontrolEt = new OgrenciyiKontrolEt(no_ogr, OgrenciEkleActivity.this, isDuplicate -> { // 所有判断逻辑都放到回调里,这时候才是拿到数据库校验结果之后 if(isDuplicate){ AlertDialog.Builder builder = new AlertDialog.Builder(OgrenciEkleActivity.this); builder.setIcon(R.drawable.warningicon); builder.setMessage(no_ogr+" numaralı öğrenci zaten kayıtlı lütfen farklı bir numara giriniz."); builder.setTitle("UYARI"); builder.setPositiveButton("TAMAM", null); builder.show(); } else { linkedHashMap.put("name",ad_ogr); linkedHashMap.put("lastname",soyisim_ogr); linkedHashMap.put("number",no_ogr); linkedHashMap.put("email",email_ogr); linkedHashMap.put("password",parola_ogr); mFirestore.collection("Students").add(linkedHashMap) .addOnSuccessListener(documentReference -> { Toast.makeText(OgrenciEkleActivity.this,"Öğrenci başaralı bir şekilde eklendi.",Toast.LENGTH_LONG).show(); }) .addOnFailureListener(e -> { Toast.makeText(OgrenciEkleActivity.this,"Öğrenci eklerken bir hata ile karşılaşıldı.",Toast.LENGTH_LONG).show(); }); } }); ogrenciyiKontrolEt.OGR_KONTROL(); }
额外性能优化建议
你现在的查重逻辑是每次都拉取整个Students集合遍历,数据量多了之后性能会非常差,建议直接用Firestore的条件查询,只查学号匹配的文档,效率更高:
// OGR_KONTROL方法里的查询改成条件查询,不用拉全量 firebaseFirestoreDb.collection("Students") .whereEqualTo("number", ogrenci_no) // 直接过滤学号相等的文档 .limit(1) // 只查1条就够 .get() .addOnSuccessListener(queryDocumentSnapshots -> { // 如果查询结果不为空就说明有重复 listener.onCheckResult(!queryDocumentSnapshots.isEmpty()); });
内容的提问来源于stack exchange,提问作者partizal
相关产品推荐
相关产品推荐

