You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android学生注册系统中Singleton类flag返回null的问题如何解决?

问题根因

你遇到的问题本质是Firestore数据库操作是异步执行的:

  • 调用ogrenciyiKontrolEt.OGR_KONTROL()后,数据库请求会在后台线程执行,不会阻塞当前主线程
  • 你紧接着直接调用singleton.getflag()的时候,数据库的onSuccess回调还没触发,自然拿不到被修改后的flag值

修复方案

方案1:用回调接口替代Singleton全局变量(推荐)

这种方式更符合异步逻辑,也避免Singleton全局状态带来的脏数据问题:

  1. 先定义回调接口
public interface OnStudentCheckListener {
    void onCheckResult(boolean isDuplicate);
}
  1. 修改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); // 出错默认不拦截,可根据业务调整
                });
    }
}
  1. 修改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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 14:54:02