Android Studio中基于OkHttp4.4.0同步解析两个JSON的实现方法
Hey there! Let's break down how to achieve your requirement—fetching and parsing two JSONs sequentially using OkHttp 4.4.0—step by step. We'll replace the deprecated AsyncTask approach with OkHttp's async calls, which is more efficient and modern for Android network operations.
Step 1: Add OkHttp Dependency
First, add the OkHttp 4.4.0 dependency to your module-level build.gradle file (usually under app/build.gradle):
dependencies { implementation 'com.squareup.okhttp3:okhttp:4.4.0' implementation 'org.json:json:20230618' // Optional but recommended for up-to-date JSON parsing utilities }
Step 2: Add Internet Permission
Make sure you have the internet permission in your AndroidManifest.xml to allow network requests:
<uses-permission android:name="android.permission.INTERNET" /> <!-- If targeting Android 9 (API 28) or higher and using HTTP URLs, add this to the <application> tag --> <application ... android:usesCleartextTraffic="true"> ... </application>
Step 3: Create a Reusable OkHttpClient Instance
OkHttp recommends reusing a single client instance to save resources. Declare this in your Activity/Fragment:
private OkHttpClient okHttpClient = new OkHttpClient();
Step 4: Fetch the First JSON & Extract the Second URL
Create a method to fetch the first JSON, parse out the second JSON's URL, then trigger the second request:
private void fetchSecondJsonUrl() { // Replace "MyFirstJSONURL" with your actual first JSON endpoint Request firstRequest = new Request.Builder() .url("MyFirstJSONURL") .build(); okHttpClient.newCall(firstRequest).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // Handle request failure (run on UI thread to update user-facing elements) runOnUiThread(() -> { // Example: Toast.makeText(MainActivity.this, "Failed to fetch first JSON", Toast.LENGTH_SHORT).show(); }); e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful() && response.body() != null) { String firstJsonString = response.body().string(); try { // Parse the first JSON to get the second URL JSONObject mainObj = new JSONObject(firstJsonString); JSONObject urlContainer = mainObj.getJSONObject("Url"); String secondJsonUrl = urlContainer.getString("Url"); // Now fetch and parse the second JSON fetchAndParseSecondJson(secondJsonUrl); } catch (JSONException e) { e.printStackTrace(); runOnUiThread(() -> { // Example: Toast.makeText(MainActivity.this, "Failed to parse first JSON", Toast.LENGTH_SHORT).show(); }); } } else { runOnUiThread(() -> { // Example: Toast.makeText(MainActivity.this, "First request failed", Toast.LENGTH_SHORT).show(); }); } } }); }
Step 5: Fetch & Parse the Second JSON
Create another method to handle the second JSON request and parse all its fields. We'll use simple model classes to store parsed data for better readability:
First, Create Model Classes
// NewsItem.java - Stores data from the "News" array public class NewsItem { private String title; private String description; private String imageUrl; public NewsItem(String title, String description, String imageUrl) { this.title = title; this.description = description; this.imageUrl = imageUrl; } // Getters for accessing data public String getTitle() { return title; } public String getDescription() { return description; } public String getImageUrl() { return imageUrl; } } // ClassItem.java - Stores data from the "Class" array (avoid using "Class" as class name since it's a Java keyword) public class ClassItem { private String title; private String description; private String imageUrl; public ClassItem(String title, String description, String imageUrl) { this.title = title; this.description = description; this.imageUrl = imageUrl; } // Getters public String getTitle() { return title; } public String getDescription() { return description; } public String getImageUrl() { return imageUrl; } }
Then, the Parsing Method
private void fetchAndParseSecondJson(String secondJsonUrl) { Request secondRequest = new Request.Builder() .url(secondJsonUrl) .build(); okHttpClient.newCall(secondRequest).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(() -> { // Example: Toast.makeText(MainActivity.this, "Failed to fetch second JSON", Toast.LENGTH_SHORT).show(); }); e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful() && response.body() != null) { String secondJsonString = response.body().string(); try { JSONObject mainJsonObj = new JSONObject(secondJsonString); // Parse "Head" section JSONObject headObj = mainJsonObj.getJSONObject("Head"); String appVersion = headObj.getString("Version"); String website = headObj.getString("WebSite"); String instagram = headObj.getString("Instagram"); String telegram = headObj.getString("Telegram"); // Parse "Banner" section JSONObject bannerObj = mainJsonObj.getJSONObject("Banner"); String bannerTitle = bannerObj.getString("Banner_Tittle"); String bannerDesc = bannerObj.getString("Banner_Description"); // Parse "Version_Banner" section JSONObject versionBannerObj = mainJsonObj.getJSONObject("Version_Banner"); String versionBannerTitle = versionBannerObj.getString("Version_Banner_Tittle"); String versionBannerDesc = versionBannerObj.getString("Version_Banner_Description"); String versionBannerLink = versionBannerObj.getString("Version_Banner_Link"); // Parse "News" array JSONArray newsArray = mainJsonObj.getJSONArray("News"); List<NewsItem> newsList = new ArrayList<>(); for (int i = 0; i < newsArray.length(); i++) { JSONObject newsObj = newsArray.getJSONObject(i); NewsItem news = new NewsItem( newsObj.getString("Tittle"), newsObj.getString("Description"), newsObj.getString("Image") ); newsList.add(news); } // Parse "Class" array JSONArray classArray = mainJsonObj.getJSONArray("Class"); List<ClassItem> classList = new ArrayList<>(); for (int i = 0; i < classArray.length(); i++) { JSONObject classObj = classArray.getJSONObject(i); ClassItem classItem = new ClassItem( classObj.getString("Tittle"), classObj.getString("Description"), classObj.getString("Image") ); classList.add(classItem); } // All data parsed successfully! Update UI on the main thread runOnUiThread(() -> { // Use the parsed data here (e.g., populate RecyclerViews, update TextViews) // Example: tvVersion.setText(appVersion); }); } catch (JSONException e) { e.printStackTrace(); runOnUiThread(() -> { // Example: Toast.makeText(MainActivity.this, "Failed to parse second JSON", Toast.LENGTH_SHORT).show(); }); } } else { runOnUiThread(() -> { // Example: Toast.makeText(MainActivity.this, "Second request failed", Toast.LENGTH_SHORT).show(); }); } } }); }
Step 6: Trigger the Workflow
Call the initial method from your Activity's onCreate (or any appropriate lifecycle method):
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Start the sequential JSON fetch and parse process fetchSecondJsonUrl(); }
Key Notes to Remember
- UI Updates: OkHttp callbacks run on a background thread, always use
runOnUiThread(or aHandler) to update UI elements. - Error Handling: We added basic error handling, but you can expand it to show user-friendly messages or retry logic.
- OkHttpClient Reuse: Reusing the same
OkHttpClientinstance is crucial for performance—avoid creating a new one for each request.
内容的提问来源于stack exchange,提问作者Alirezaarabi

