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

Retrofit对象构造报错求助:Logcat在Client构造方法处提示异常

我瞅见问题出在哪了——你Client类构造方法里的异常,根源是把API密钥当成了Retrofit的baseUrl来用,这完全不符合Retrofit的要求。咱们一步步来修复:

问题分析与修复方案

1. 核心错误:Retrofit的baseUrl配置完全错误

Retrofit的baseUrl()方法需要传入的是API服务的基础地址(比如新闻API的https://newsapi.org/v2/),而不是你的API密钥。你现在把密钥传进去,Retrofit根本无法识别这个“URL”,自然会抛出异常。

2. 次要问题:未初始化集合导致空指针

你的MainActivity里,articleList只做了声明却没初始化,当你在onResponse里调用articleList.clear()时,肯定会触发NullPointerException。


修复后的Client类代码

package com.example.news.retrofit;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class Client {
    // 替换成你使用的新闻API的基础地址,这里以NewsAPI为例
    private static final String BASE_URL = "https://newsapi.org/v2/";
    private static final String KEY = "3eec6a8558e24defb8a30fea138c5eee";
    private static Retrofit retrofit;
    private static Client client;
    private Client() {
        // 用正确的baseUrl初始化Retrofit
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }
    public static synchronized Client getInstance() {
        if (client == null) {
            client = new Client();
        }
        return client;
    }
    public IRequest getApi() {
        return retrofit.create(IRequest.class);
    }
}

修复后的MainActivity类代码

package com.example.news;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.util.Log;
import com.example.news.adapter.NewsAdapter;
import com.example.news.key.Key;
import com.example.news.retrofit.Client;
import com.example.news.retrofit.IRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
    RecyclerView recyclerView;
    NewsAdapter newsAdapter;
    Key apiKey = Key.API_KEY;
    // 初始化集合,避免空指针异常
    List<Article> articleList = new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        final String country = getCountry();
        fetchApi(country);
    }
    private void fetchApi(String country) {
        Call<HeadLines> headLinesCall = Client.getInstance().getApi().getHeadlines(country, apiKey.getValue());
        headLinesCall.enqueue(new Callback<HeadLines>() {
            @Override
            public void onResponse(Call<HeadLines> call, Response<HeadLines> response) {
                // 增加对response.body()的非空判断,避免潜在异常
                if (response.isSuccessful() && response.body() != null && response.body().getArticles() != null) {
                    articleList.clear();
                    articleList.addAll(response.body().getArticles());
                    // 优化Adapter的创建逻辑,避免重复实例化
                    if (newsAdapter == null) {
                        newsAdapter = new NewsAdapter(MainActivity.this, articleList);
                        recyclerView.setAdapter(newsAdapter);
                    } else {
                        newsAdapter.notifyDataSetChanged();
                    }
                }
            }
            @Override
            public void onFailure(Call<HeadLines> call, Throwable t) {
                Log.d(this.getClass().getCanonicalName(), "onFailure: " + t.getMessage());
            }
        });
    }
    private String getCountry() {
        Locale locale = Locale.getDefault();
        return locale.getCountry().toLowerCase();
    }
}

额外需要检查的点

  1. 确保你的IRequest接口注解正确,比如针对NewsAPI的接口应该是这样:
public interface IRequest {
    @GET("top-headlines")
    Call<HeadLines> getHeadlines(
            @Query("country") String country,
            @Query("apiKey") String apiKey
    );
}
  1. 确认你在AndroidManifest.xml中声明了网络权限:
<uses-permission android:name="android.permission.INTERNET" />
  1. 如果你使用的不是NewsAPI,记得把BASE_URL替换成对应服务的真实基础地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 11:22:47