Android中Retrofit调用API失效问题排查与解决求助
API调用失败排查与解决方案
此前可正常调用API,现在无法运行,已确认IPv4地址无异常,以下是提供的代码文件及排查修复方案:
代码文件
circularNotice.java
package com.example.college_connect_faculty; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; import android.os.Build; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.FirebaseApp; import com.google.firebase.messaging.FirebaseMessaging; import java.io.IOException; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; public class circularNotice extends AppCompatActivity { EditText noticetxt,noticeTitle; Button noticeBtn; TextView stringLength; String topic = "com.example.college_connect_faculty"; @Override protected void onCreate(Bundle savedInstanceState) { FirebaseApp.initializeApp(this); super.onCreate(savedInstanceState); setContentView(R.layout.activity_circular_notice); FirebaseMessaging.getInstance().subscribeToTopic("all"); noticetxt = findViewById(R.id.noticetxt); noticeBtn = findViewById(R.id.noticeBtn); stringLength = findViewById(R.id.stringLength); noticeTitle = findViewById(R.id.noticeTitle); noticetxt.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void afterTextChanged(Editable editable) { String s = noticetxt.getText().toString(); int l = s.length(); stringLength.setText(String.valueOf(l)); } }); noticeBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String notice = noticetxt.getText().toString(); String title = noticeTitle.getText().toString(); try { Call<ResponseBody> call = RetrofitClient.getInstance().getApi().noticeUpload(notice, title); call.enqueue(new Callback<ResponseBody>() { @RequiresApi(api = Build.VERSION_CODES.Q) @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { try { String s = response.body().string(); Toast.makeText(circularNotice.this, s, Toast.LENGTH_SHORT).show(); FcmNotificationsSender notificationsSender = new FcmNotificationsSender("/topics/all", title, notice, getApplicationContext(), circularNotice.this); notificationsSender.SendNotifications(); FirebaseMessaging firebaseMessaging = FirebaseMessaging.getInstance(); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) {} }); }catch (Exception e){ Toast.makeText(circularNotice.this,e.getMessage().toString(),Toast.LENGTH_SHORT).show(); } } }); } }
api.java
package com.example.college_connect_faculty; import okhttp3.MultipartBody; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.Field; import retrofit2.http.FormUrlEncoded; import retrofit2.http.Multipart; import retrofit2.http.POST; import retrofit2.http.Part; public interface api { @FormUrlEncoded @POST("uploadSubjects.php") Call<ResponseBody>uploadSubject( @Field("semester") String semester, @Field("branch") String branch, @Field("subject")String subject ); @FormUrlEncoded @POST("showSubjects.php") Call<ResultSubject> showSubject( @Field("semester") String semester, @Field("branch") String branch ); @Multipart @POST("filesUpload.php") Call<ResponseBody> fileUpload( @Part MultipartBody.Part fileName, @Part("branch") RequestBody branch, @Part("semester") RequestBody semester, @Part("subject") RequestBody subject ); @FormUrlEncoded @POST("noticeUpload.php") Call<ResponseBody> noticeUpload( @Field("notice") String notice, @Field("title") String title ); }
Retrofitclient.java
package com.example.college_connect_faculty; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; public class RetrofitClient { final String BASE_URL = "http://192.168.153.223/college_connect/"; private static RetrofitClient mInstance; Retrofit retrofit; RetrofitClient(){ retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()) .build(); } public static synchronized RetrofitClient getInstance(){ if (mInstance==null){ mInstance = new RetrofitClient(); } return mInstance; } public api getApi(){ return retrofit.create(api.class); } }
排查与修复方案
1. 补全错误捕获逻辑
当前代码onFailure方法为空,无法定位失败原因,先修改该方法:
@Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.e("API_ERROR", "调用失败: " + t.getMessage()); Toast.makeText(circularNotice.this, "调用失败: " + t.getMessage(), Toast.LENGTH_LONG).show(); }
同时在onResponse中增加HTTP状态码判断,避免空指针异常:
@RequiresApi(api = Build.VERSION_CODES.Q) @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (response.isSuccessful()) { try { String s = response.body().string(); Toast.makeText(circularNotice.this, s, Toast.LENGTH_SHORT).show(); // 推送逻辑... } catch (IOException e) { Log.e("RESPONSE_ERROR", "解析响应失败", e); Toast.makeText(circularNotice.this, "解析响应失败", Toast.LENGTH_SHORT).show(); } } else { try { String errorBody = response.errorBody().string(); Log.e("API_ERROR", "HTTP错误: " + response.code() + ",内容: " + errorBody); Toast.makeText(circularNotice.this, "请求错误: " + response.code(), Toast.LENGTH_SHORT).show(); } catch (IOException e) { Log.e("API_ERROR", "获取错误响应失败", e); } } }
2. 验证网络连通性
- 用浏览器访问
http://192.168.153.223/college_connect/noticeUpload.php,确认服务器能正常响应(哪怕返回错误信息,只要能连通即可)。 - 检查服务器端Apache/Nginx服务是否启动,
noticeUpload.php文件是否存在且权限正确。
3. 适配Android网络规则
- 确保
AndroidManifest.xml添加了网络权限:
<uses-permission android:name="android.permission.INTERNET" />
- Android 9及以上需允许明文HTTP访问,创建
res/xml/network_security_config.xml:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">192.168.153.223</domain> </domain-config> </network-security-config>
并在AndroidManifest.xml的application标签中引用:
android:networkSecurityConfig="@xml/network_security_config"
4. 添加请求日志拦截器
添加OkHttp日志拦截器,查看完整请求/响应细节:
- 在
build.gradle(Module)中添加依赖:
implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
- 修改
RetrofitClient初始化代码:
RetrofitClient(){ HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(logging) .build(); retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build(); }
Logcat会输出请求URL、参数、响应内容,快速定位问题。
5. 检查服务器端脚本
在noticeUpload.php中添加测试输出,验证参数是否正常接收:
<?php // 测试用:直接返回接收的参数 $notice = $_POST['notice'] ?? '无参数'; $title = $_POST['title'] ?? '无参数'; echo "收到通知: $title - $notice"; // 原业务逻辑... ?>
如果客户端能收到该测试内容,说明问题出在服务器端业务逻辑(如数据库连接错误)。
内容的提问来源于stack exchange,提问作者Jaivik Kotadiya
相关产品推荐
相关产品推荐

