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

登录界面ProgressDialog卡顿,无法启动新Activity问题求助

解决SignIn界面ProgressDialog卡顿及无法启动Activity的问题

看了你的代码和调试日志,我来帮你梳理问题根源和对应的修复方案:

1. 核心卡顿原因:Firebase监听使用不当

你在登录逻辑里用了addValueEventListener,这个方法会持续监听数据节点的所有变化,但登录只需要单次查询用户信息就够了。这种永久监听会导致:

  • 不必要的重复回调,占用UI线程资源引发卡顿
  • 登录成功后监听依然存在,浪费设备资源

修复方案:把addValueEventListener替换为addListenerForSingleValueEvent,它只会执行一次数据查询,完成后自动取消监听:

users.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        // 保留你原有的用户校验逻辑
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // 这里必须关闭Dialog,避免请求失败后弹窗一直挂着
        mDialog.dismiss();
        Toast.makeText(SignIn.this,"登录请求失败:"+databaseError.getMessage(),Toast.LENGTH_SHORT).show();
    }
});

2. ProgressDialog生命周期管理漏洞

你的代码只在onDataChange里关闭Dialog,但如果网络中断、请求被取消,Dialog会一直停留在界面,造成"卡顿"的假象。

修复方案:

  • 必须在onCancelled方法中也调用mDialog.dismiss()
  • 可以在Activity销毁时做兜底处理,避免内存泄漏:
@Override
protected void onDestroy() {
    super.onDestroy();
    if(mDialog != null && mDialog.isShowing()){
        mDialog.dismiss();
    }
}

3. 日志中RippleDrawable报错(非卡顿主因)

日志里的Could not find class 'android.graphics.drawable.RippleDrawable'是AppCompat库的兼容警告——你的设备API版本低于21(RippleDrawable在API21才引入)。这个警告不影响功能,若要消除可以:

  • 升级app/build.gradle里的AppCompat库到最新稳定版
  • 把布局中类似android:background="?attr/selectableItemBackground"的属性,替换为AppCompat兼容的app:background="?attr/selectableItemBackground"

4. 代码结构优化(提升可读性与稳定性)

你把signInUser方法嵌套在onClick监听内部,虽然语法合法,但可读性差还可能引发上下文引用问题。建议提取为Activity的成员方法:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sign_in);
    // 初始化控件...
    
    btnSignIn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            signInUser(edtPhone.getText().toString(),edtPassword.getText().toString());
        }
    });
}

// 提取为独立的成员方法
private void signInUser(String phone, String password) {
    final ProgressDialog mDialog=new ProgressDialog(SignIn.this);
    mDialog.setMessage("Please wait...");
    mDialog.show();
    final String localPhone=phone;
    final String localPassword=password;
    
    users.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            mDialog.dismiss();
            if (dataSnapshot.child(localPhone).exists()) {
                User user=dataSnapshot.child(localPhone).getValue(User.class);
                user.setPhone(localPhone);
                if (Boolean.parseBoolean(user.getIsStaff())) {
                    if (user.getPassword().equals(localPassword)) {
                        Intent login =new Intent(SignIn.this,Home.class);
                        Common.currentUser=user;
                        startActivity(login);
                        finish();
                    } else {
                        Toast.makeText(SignIn.this,"Wrong password",Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(SignIn.this,"Login with staff account",Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(SignIn.this,"User not exist in database..",Toast.LENGTH_SHORT).show();
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            mDialog.dismiss();
            Toast.makeText(SignIn.this,"Login failed: "+databaseError.getMessage(),Toast.LENGTH_SHORT).show();
        }
    });
}

额外小建议

  • 登录前先做输入校验(比如手机号、密码是否为空),避免无效的网络请求
  • 考虑用AlertDialog或Material Design的DialogFragment替代已被废弃的ProgressDialog(Android O开始标记为废弃)

内容的提问来源于stack exchange,提问作者Bhaskar Joshi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:37:41