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

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日志拦截器,查看完整请求/响应细节:

  1. 在build.gradle(Module)中添加依赖:
implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
  1. 修改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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 03:39:21