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

Android开发求助:URL获取JSON数据无法在RecyclerView中显示

Hey Vinay, let's break down why your activity_swami is showing blank when fetching JSON from a URL—since static local data works, your RecyclerView setup is probably solid, so the issue is likely tied to network fetching, JSON parsing, or how you're updating the adapter after getting data. Let's go through the key checks and fixes step by step:

1. First, Verify Network Permissions & Cleartext Traffic

Android blocks network operations without explicit permissions, and restricts plain HTTP requests by default on newer versions:

  • Add these permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  • If your JSON URL uses HTTP (not HTTPS), create a res/xml/network_security_config.xml file to allow cleartext traffic:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

Then link it in your AndroidManifest.xml's application tag:

android:networkSecurityConfig="@xml/network_security_config"
2. Never Run Network Requests on the Main Thread

Android throws a NetworkOnMainThreadException if you try to fetch data directly on the UI thread. Use a background thread + main thread update for UI changes. For beginners, coroutines are a simple, modern approach:
First add coroutine dependencies to your app/build.gradle:

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3"
}

Then update your swami.java to handle the request safely:

import kotlinx.coroutines.CoroutineScope;
import kotlinx.coroutines.Dispatchers;
import kotlinx.coroutines.launch;
import kotlinx.coroutines.withContext;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

// Inside your swami Activity
private void fetchJsonFromUrl() {
    CoroutineScope(Dispatchers.IO).launch(() -> {
        try {
            // Replace with your actual JSON URL
            URL url = new URL("https://your-json-api-url.com/data");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder responseBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                responseBuilder.append(line);
            }
            reader.close();
            conn.disconnect();

            // Parse JSON and update UI on main thread
            String jsonResponse = responseBuilder.toString();
            withContext(Dispatchers.Main, () -> {
                parseJsonAndUpdateRecyclerView(jsonResponse);
            });
        } catch (Exception e) {
            e.printStackTrace();
            // Show error toast on main thread
            withContext(Dispatchers.Main, () -> {
                Toast.makeText(swami.this, "Failed to load data", Toast.LENGTH_SHORT).show();
            });
        }
    });
}
3. Validate JSON Parsing Logic

Since local data works, your adapter/viewholder is fine—double-check that your parsing matches the JSON structure exactly (field names are case-sensitive!):

import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;

// Replace YourModelClass with your actual data model
private void parseJsonAndUpdateRecyclerView(String json) {
    try {
        JSONArray jsonArray = new JSONArray(json);
        List<YourModelClass> dataList = new ArrayList<>();

        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject itemObj = jsonArray.getJSONObject(i);
            // Match keys to your JSON's actual field names
            String title = itemObj.getString("card_title");
            String content = itemObj.getString("card_content");
            dataList.add(new YourModelClass(title, content));
        }

        // Update RecyclerView adapter
        YourRecyclerAdapter adapter = new YourRecyclerAdapter(dataList);
        RecyclerView recyclerView = findViewById(R.id.your_recycler_view_id);
        recyclerView.setAdapter(adapter);
    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(this, "Failed to parse data", Toast.LENGTH_SHORT).show();
    }
}
4. Confirm RecyclerView Initialization is Complete

Make sure you've set up the LayoutManager in swami.java's onCreate method (local data works, but double-check anyway):

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_swami);

    RecyclerView recyclerView = findViewById(R.id.your_recycler_view_id);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setHasFixedSize(true); // Improves performance

    // Call your fetch method here
    fetchJsonFromUrl();
}
5. Debugging Tips to Narrow Down Issues
  • Check Logcat for errors: Search for NetworkOnMainThreadException, JSONException, or IO errors to pinpoint failures
  • Test your JSON URL in a browser/Postman first to confirm it returns valid JSON
  • Replace your URL with a public test API (like https://jsonplaceholder.typicode.com/users) to rule out issues with your endpoint

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:18:51