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

Android Studio基于OkHttp实现API对接ListView功能求助

代码问题汇总
  • API类构造函数未给成员变量teamName赋值,传入的查询参数没有被拼接到请求URL中,接口拿不到查询关键词。
  • 异步逻辑嵌套错误:同时使用AsyncTask和OkHttp异步enqueue方法,doInBackground方法会在OkHttp请求返回前就执行结束,调用getTeamsInfo()永远只能拿到空列表。
  • Gson解析逻辑错误:现有Data类仅对应单条球队数据,未匹配接口返回的外层JSON结构,且代码中存在未定义的lst类、TAG常量、Data()方法,无法通过编译。
  • 线程使用违规:OkHttp回调运行在子线程,直接在回调中执行Toast弹出、ListView更新等UI操作会触发安卓线程异常,所有UI操作必须切换到主线程执行。
  • 冗余代码过多:导入了大量未使用的类,增加编译负担。
修正实现方案

第一步:调整实体类结构

删掉原Data类中冗余的手动解析方法,新增外层响应包装类匹配API返回结构:

// 单条球队数据实体,建议重命名为Team语义更清晰
import com.google.gson.annotations.SerializedName;
public class Team {
    @SerializedName("team")
    private String team;
    @SerializedName("played")
    private String played;
    @SerializedName("win")
    private String win;
    @SerializedName("draw")
    private String draw;
    @SerializedName("loss")
    private String loss;
    @SerializedName("goalsFor")
    private String goalsFor;
    @SerializedName("goalsAgainst")
    private String goalsAgainst;
    @SerializedName("points")
    private String points;

    public String getTeam() {return team;}
    public String getPlayed() {return played;}
    public String getWin() {return win;}
    public String getDraw() {return draw;}
    public String getLoss() {return loss;}
    public String getGoalsFor() {return goalsFor;}
    public String getGoalsAgainst() {return goalsAgainst;}
    public String getPoints() {return points;}
}

// 外层API响应包装类,匹配接口返回的JSON结构
public class ApiResponse {
    @SerializedName("teams")
    private List<Team> teams;
    public List<Team> getTeams() {return teams;}
}

第二步:重构页面请求逻辑

删掉冗余的AsyncTask嵌套,直接使用OkHttp发起异步请求,请求完成后切主线程更新列表:

package com.example.myapplication;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import com.google.gson.Gson;
import java.io.IOException;
import java.util.ArrayList;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class TopScorer extends AppCompatActivity {
    private SearchView searchView;
    private ListView listView;
    private ArrayAdapter<String> arrayAdapter;
    private ArrayList<String> displayList = new ArrayList<>();
    private final OkHttpClient client = new OkHttpClient();
    private static final String API_KEY = "6ad8dfcfcbmshb4a45a22532e4a1p1efecajsnc2fb433de0da";
    private static final String API_HOST = "heisenbug-premier-league-live-scores-v1.p.rapidapi.com";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_top_scorer);
        searchView = findViewById(R.id.search);
        listView = findViewById(R.id.listview);

        // 适配器仅初始化一次
        arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, displayList);
        listView.setAdapter(arrayAdapter);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                fetchTeamData(query.trim());
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                return false;
            }
        });
    }

    private void fetchTeamData(String teamName) {
        String requestUrl = "https://heisenbug-premier-league-live-scores-v1.p.rapidapi.com/api/premierleague/team?name=" + teamName;
        Request request = new Request.Builder()
                .url(requestUrl)
                .get()
                .addHeader("X-RapidAPI-Key", API_KEY)
                .addHeader("X-RapidAPI-Host", API_HOST)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                runOnUiThread(() -> Toast.makeText(TopScorer.this, "请求失败,请检查网络", Toast.LENGTH_SHORT).show());
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (!response.isSuccessful()) {
                    runOnUiThread(() -> Toast.makeText(TopScorer.this, "请求异常,错误码:" + response.code(), Toast.LENGTH_SHORT).show());
                    return;
                }
                String responseStr = response.body().string();
                Gson gson = new Gson();
                ApiResponse apiResponse = gson.fromJson(responseStr, ApiResponse.class);
                
                displayList.clear();
                int index = 1;
                if (apiResponse.getTeams() != null) {
                    for (Team team : apiResponse.getTeams()) {
                        displayList.add(index + ". 球队:" + team.getTeam());
                        displayList.add("出场次数:" + team.getPlayed());
                        displayList.add("胜场:" + team.getWin());
                        displayList.add("平场:" + team.getDraw());
                        displayList.add("负场:" + team.getLoss());
                        displayList.add("进球数:" + team.getGoalsFor());
                        displayList.add("失球数:" + team.getGoalsAgainst());
                        displayList.add("积分:" + team.getPoints());
                        displayList.add("");
                        index++;
                    }
                }

                // 切主线程刷新UI
                runOnUiThread(() -> {
                    if (displayList.isEmpty()) {
                        Toast.makeText(TopScorer.this, "未查询到对应球队数据", Toast.LENGTH_SHORT).show();
                    }
                    arrayAdapter.notifyDataSetChanged();
                });
            }
        });
    }
}
配置注意事项
  • 确认AndroidManifest.xml中已添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
  • 本次调用的接口为HTTPS协议,无需额外配置Android 9+的明文网络访问规则。
  • 不要重复创建ArrayAdapter实例,初始化一次后仅更新数据源、调用notifyDataSetChanged()刷新即可,减少性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:51:27