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
相关产品推荐
相关产品推荐

