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

解析NewsAPI的JSON数据后RecyclerView无内容显示问题求助

问题排查与修复方案

我帮你找出了代码里的几个核心问题,咱们一步步来解决:

核心问题分析

  1. JSON解析逻辑错误:你请求返回的JSON根节点是一个JSONObject,里面包含articles数组,但你直接把整个响应当成JSONArray解析,这必然会抛出JSON异常。
  2. AsyncTask逻辑混乱:你在后台线程调用了parseResult(UI操作不能在后台执行),而且doInBackground返回的result始终是null,导致onPostExecute里的解析完全无效。
  3. Adapter数据更新缺失:初始化时modelList是null,即使后续解析出数据,Adapter也不知道数据变化,没有触发刷新。

分步修复代码

1. 修正JSON解析逻辑

把根节点当作JSONObject处理,取出里面的articles数组再解析:

private void parseResult(String result){
    try {
        JSONObject rootObject = new JSONObject(result);
        JSONArray posts = rootObject.getJSONArray("articles"); // 取出真正的文章数组
        modelList.clear(); // 先清空旧数据
        for (int i=0;i<posts.length();i++){
            JSONObject post = posts.optJSONObject(i);
            Model item = new Model();
            item.setAuthor(post.optString("author"));
            item.setTitle(post.optString("title"));
            item.setDescription(post.optString("description"));
            // 可以按需添加其他字段,比如urlToImage、publishedAt等
            modelList.add(item);
            Log.d("AuthorForJSON : ", post.optString("author"));
        }
        // 解析完成后通知Adapter刷新
        customAdapter.notifyDataSetChanged();
    } catch (JSONException e) {
        e.printStackTrace();
        Toast.makeText(this, "数据解析失败", Toast.LENGTH_SHORT).show();
    }
}

2. 修复AsyncTask的执行逻辑

后台线程只负责获取网络响应,把解析操作放到onPostExecute(UI线程)中执行:

public class DownloadTask extends AsyncTask<String,Void,String> {
    private ProgressDialog progressDialog=new ProgressDialog(MainActivity.this);

    @Override
    protected void onPreExecute() {
        progressDialog.setMessage("Loading...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }

    @Override
    protected String doInBackground(String... strings) {
        StringBuilder response = new StringBuilder();
        try {
            URL url = new URL(strings[0]);
            HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
            int statusCode = urlConnection.getResponseCode();
            if (statusCode == HttpsURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(urlConnection.getInputStream()));
                String line;
                while ((line = br.readLine()) != null) {
                    response.append(line);
                }
            } else {
                runOnUiThread(() -> Toast.makeText(getApplicationContext(), "请求失败,状态码:" + statusCode, Toast.LENGTH_LONG).show());
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
            runOnUiThread(() -> Toast.makeText(getApplicationContext(), "URL格式错误", Toast.LENGTH_LONG).show());
        } catch (IOException e) {
            e.printStackTrace();
            runOnUiThread(() -> Toast.makeText(getApplicationContext(), "网络异常", Toast.LENGTH_LONG).show());
        } catch (Exception e) {
            e.printStackTrace();
            runOnUiThread(() -> Toast.makeText(getApplicationContext(), "未知错误", Toast.LENGTH_LONG).show());
        }
        Log.d("ResponseForParsing : ", response.toString());
        return response.toString(); // 返回完整的响应字符串
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
        if (result != null && !result.isEmpty()) {
            parseResult(result); // 在UI线程解析数据
        } else {
            Toast.makeText(getApplicationContext(), "未获取到有效数据", Toast.LENGTH_LONG).show();
        }
    }
}

3. 修正Adapter初始化与数据绑定

确保Adapter持有有效的空列表,并完善ViewHolder的绑定逻辑:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
    private Context context;
    private List<Model> modelList;

    public CustomAdapter(Context context, List<Model> modelList) {
        this.context = context;
        this.modelList = modelList != null ? modelList : new ArrayList<>(); // 避免null引用
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Model item = modelList.get(position);
        // 根据你的row布局控件ID修改
        holder.authorTv.setText(item.getAuthor());
        holder.titleTv.setText(item.getTitle());
        holder.descTv.setText(item.getDescription());
    }

    @Override
    public int getItemCount() {
        return modelList.size();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        TextView authorTv;
        TextView titleTv;
        TextView descTv;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            authorTv = itemView.findViewById(R.id.author_text);
            titleTv = itemView.findViewById(R.id.title_text);
            descTv = itemView.findViewById(R.id.desc_text);
        }
    }
}

4. 修正MainActivity的初始化逻辑

确保modelList初始化为空列表,避免Adapter持有null引用:

private List<Model> modelList = new ArrayList<>(); // 初始化为空列表
private CustomAdapter customAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    recyclerView = findViewById(R.id.list);
    recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
    customAdapter = new CustomAdapter(MainActivity.this, modelList);
    recyclerView.setAdapter(customAdapter);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    new DownloadTask().execute(url);
}

额外注意事项

  • 确保你的Model类有对应的getter方法(比如getAuthor()、getTitle()),否则Adapter无法获取数据。
  • 在AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" />。
  • AsyncTask已被官方废弃,建议后续学习使用Coroutines+OkHttp+ViewModel的组合来处理网络请求,更符合现代Android开发规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:54:03