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

Android Retrofit+OkHttp3登录注册:数据入库成功但无Toast及跳转

问题分析与解决方案

从你的描述和日志来看,问题出在两个核心地方:响应状态码判断逻辑和JSON解析字段与后端返回结构不匹配,同时代码里的成功判断逻辑也存在反转问题。

1. 为什么response.isSuccessful()会返回false?

你看到数据已经成功插入数据库,但代码却走到了else分支打印Register Failed,这说明response.isSuccessful()返回了false。这个方法的判断依据是HTTP状态码是否在200-299区间内,所以第一步要先明确后端返回的状态码到底是什么。

建议在onResponse方法开头添加日志,打印状态码和响应信息:

@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
    // 先打印状态码和响应信息,排查核心问题
    Log.i("debug", "Response Code: " + response.code());
    Log.i("debug", "Response Message: " + response.message());
    
    // 原有的后续代码...
}

如果后端确实返回了成功的响应体,但状态码不是2xx(比如错误返回了400),那需要和后端同学确认状态码的规范;如果状态码是2xx但isSuccessful()仍为false,可能是OkHttp的配置问题,但这种情况比较少见。

2. JSON解析逻辑完全不匹配后端返回结构

看你的Logcat里的实际响应体:

{"status":true,"message":"Registration Successfully, Please SignIn.","0":{"name":"test","lastname":"","username":"test",...}}

但你的代码里却在查找error和error_msg字段,还把error等于true当成注册成功的条件——这不仅字段不匹配,逻辑也完全反了!后端用status:true表示操作成功,message是对应的提示文本,和你代码里的判断逻辑完全对不上。

3. 修正后的完整代码

结合以上问题,这里给出调整后的代码:

mApiService.createUser(
        input_name.getText().toString(),
        input_lastname.getText().toString(),
        input_username.getText().toString(),
        input_email.getText().toString(),
        input_password.getText().toString(),
        input_phonenumber.getText().toString(),
        input_country.getSelectedItem().toString()
).enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        Log.i("debug", "Response Code: " + response.code());
        Log.i("debug", "Response Message: " + response.message());
        
        // 放宽判断条件:如果状态码成功,或者响应体不为null(兼容后端状态码不规范的情况)
        if (response.isSuccessful() || response.body() != null) {
            Log.i("debug", "onResponse: Successful");
            loading.dismiss();
            try {
                String responseBody = response.body().string();
                Log.i("debug", "Response Body: " + responseBody); // 打印完整响应体,方便调试
                JSONObject jsonRESULTS = new JSONObject(responseBody);
                
                // 匹配后端的status字段,true表示注册成功
                if (jsonRESULTS.getBoolean("status")) {
                    String successMsg = jsonRESULTS.getString("message");
                    Toast.makeText(mContext, successMsg, Toast.LENGTH_SHORT).show();
                    startActivity(new Intent(mContext, SignInActivity.class));
                } else {
                    // 用optString避免字段不存在时抛出异常,默认提示"Unknown error"
                    String errorMessage = jsonRESULTS.optString("message", "Unknown error");
                    Toast.makeText(mContext, errorMessage, Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException | IOException e) {
                e.printStackTrace();
                Toast.makeText(mContext, "Failed to parse server response", Toast.LENGTH_SHORT).show();
            }
        } else {
            Log.i("debug", "onResponse: Register Failed");
            loading.dismiss();
            Toast.makeText(mContext, "Server returned an error", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        Log.e("debug", "onFailure: ERROR > " + t.getMessage());
        Toast.makeText(mContext, "Connection Failed", Toast.LENGTH_SHORT).show();
        loading.dismiss(); // 网络失败时也要关闭loading,避免一直显示
    }
});

额外注意事项

  • response.body().string()只能调用一次,因为ResponseBody是一次性的流,所以先把它存入字符串再进行后续操作。
  • 在onFailure分支里一定要关闭loading,否则网络失败时loading会一直停留在界面上。
  • 使用optString代替getString可以避免因字段缺失而抛出JSONException,让代码更健壮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:20:56