当前位置: 首页 > 知识库问答 >
问题:

为什么这个Java页面没有显示来自这个Json的数据?

滕星纬
2023-03-14

大家好,我在项目中遇到了一个大问题。我发出OkHttp请求,从服务器收到响应,一切都很完美。问题是为什么我不能显示数据,我在xml和listview中创建了一个模型项(这是必需的视图),当我访问该页面时,该页面为空。

有人能帮我解决这个问题吗?

页面代码如下:

package com.example.socceraplication;

import static android.content.ContentValues.TAG;

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

import android.os.AsyncTask;
import android.os.Bundle;

import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;

import android.widget.SearchView;
import android.widget.SimpleAdapter;
import android.widget.Toast;


import com.google.gson.Gson;

import java.util.ArrayList;

import java.util.HashMap;


import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.util.ArrayList;

public class TeamInfo extends AppCompatActivity {
    private ListView lv;

    ArrayList<HashMap<String, String>> resultList;


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_team_info);

        resultList = new ArrayList<>();
        lv = (ListView) findViewById(R.id.list);
        new GetContacts().execute();

    }

    private class GetContacts extends AsyncTask<Void, Void, Void>{
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Toast.makeText(TeamInfo.this,"Json Data is downloading",Toast.LENGTH_LONG).show();
        }


        @Override
        protected Void doInBackground(Void... arg0) {
            OkHttpClient client = new OkHttpClient();

            Request request = new Request.Builder()
                    .url("https://heisenbug-premier-league-live-scores-v1.p.rapidapi.com/api/premierleague/team?name=Liverpool")
                    .get()
                    .addHeader("X-RapidAPI-Key", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
                    .addHeader("X-RapidAPI-Host", "heisenbug-premier-league-live-scores-v1.p.rapidapi.com")
                    .build();
            client.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(@NonNull Call call, @NonNull IOException e) {
                    call.cancel();
                }

                @Override
                public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {

                    String jsonStr=response.body().string();
                    Log.e(TAG, "Response from url: " + jsonStr);
                    if (jsonStr != null) {
                        try {
                            JSONObject jsonObj = new JSONObject(jsonStr);

                            // Getting JSON Array node
                            JSONArray records = jsonObj.getJSONArray("records");

                            // looping through All items
                            for (int i = 0; i < records.length(); i++) {
                                JSONObject c = records.getJSONObject(i);
                                String league = c.getString("league");
                                String season = c.getString("season");
                                String name = c.getString("name");
                                String officialName = c.getString("officialName");
                                String address = c.getString("address");
                                String telephone = c.getString("telephone");
                                String fax = c.getString("fax");
                                String website = c.getString("website");
                                String founded = c.getString("founded");
                                String teamSize = c.getString("teamSize");
                                String averageAge = c.getString("averageAge");
                                String foreigners = c.getString("foreigners");
                                String nationaTeamPlayers = c.getString("nationaTeamPlayers");
                                String teamValue = c.getString("teamValue");
                                String venue = c.getString("venue");
                                String venueCapacity = c.getString("venueCapacity");

                                HashMap<String, String> result = new HashMap<>();

                                // adding each child node to HashMap key => value
                                result.put("league",league);
                                result.put("season",season);
                                result.put("name",name);
                                result.put("officialName",officialName);
                                result.put("address",address);
                                result.put("telephone",telephone);
                                result.put("fax",fax);
                                result.put("website",website);
                                result.put("founded",founded);
                                result.put("teamSize",teamSize);
                                result.put("averageAge",averageAge);
                                result.put("foreigners",foreigners);
                                result.put("nationaTeamPlayers",nationaTeamPlayers);
                                result.put("teamValue",teamValue);
                                result.put("venue",venue);
                                result.put("venueCapacity",venueCapacity);

                                resultList.add(result);


                            }
                        } catch (final JSONException e) {
                            Log.e(TAG, "Json parsing error: " + e.getMessage());
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(getApplicationContext(),
                                            "Json parsing error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                                }
                            });
                        }
                    }else {
                        Log.e(TAG, "Couldn't get json from server.");
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getApplicationContext(),
                                        "Couldn't get json from server. Check LogCat for possible errors!",
                                        Toast.LENGTH_LONG).show();
                            }
                        });
                    }
                }
            });
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            ListAdapter adapter = new SimpleAdapter(TeamInfo.this, resultList,
                    R.layout.list_item_team, new String[]{ "league","season","name","officialName","address","telephone","fax","website","founded","teamSize","averageAge","foreigners","nationaTeamPlayers","teamValue","venue","venueCapacity"},
                    new int[]{R.id.league, R.id.season,R.id.name,R.id.officialName,R.id.address,R.id.telephone,R.id.fax,R.id.website,R.id.founded,R.id.teamSize,R.id.averageAge,R.id.foreigners,R.id.nationaTeamPlayers,R.id.teamValue,R.id.venue,R.id.venueCapacity});
            lv.setAdapter(adapter);

        }
    }
}

共有1个答案

许远航
2023-03-14

排队调用是异步的,这意味着它将在将来某个时候在后台运行的工作排队,完成后,它将运行您提供的回调(onResponse)。这意味着您的通话顺序是

  • 开始做背景
  • 将您的Http调用添加到队列
  • 从doInbackground返回
  • 运行onPostExecute
  • 将空列表发布到适配器
  • ...一段时间后...
  • 获取数据时运行onACK回调

要解决这个问题,您可以完全删除异步任务,只需将工作从主线程排队,因为它已经在后台处理了实际的请求。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_team_info);

    resultList = new ArrayList<>();
    lv = (ListView) findViewById(R.id.list);
    startRequest();
}

private void startRequest() {
    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
            //...
            .build();
            
    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            call.cancel();
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) { 
            showResult(response);
        }
    });
}

private void showResult(Response response) {
    // show the result here - no need to runOnUiThread
    // set the adapter, put text in views, etc from in here
}

如果您真的想在后台从您自己的AsyncTask进行调用,您应该使用同步API,而不是异步API。这意味着调用执行而不是入队,如下所示:

// this MUST run on a background thread or it will block the UI thread
Response response = client.newCall(request).execute();

 类似资料:
  • 错误:无法找到或加载主类MyGridLayout.MyGridLayout C:\users\home\AppData\local\netbeans\cache\8.2\executor-snippets\run.xml:53:Java返回:1构建失败(总时间:0秒)

  • Code Demo 为什么这个React Demo的列表没有展示出来? this.setState 是一个异步操作? 所以导致log时 没有输出更新后的值? 那为什么页面没有重新渲染 ?

  • 我尝试了一切,但图像不会显示出来,我试图使图像变小但没有用,我试图改变路径,我试图改变图像的位置但没有帮助,我试图在互联网上搜索但一无所获。 我看到的只是空白的图形用户界面,没有文本和图像。如果你能帮我,你会帮我一个大忙。 代码如下:

  • 我在中使用带有4.1版本模拟器的android最新版本sdk。一切都很好。但是在我的中,对于任何应用程序的每次运行,我都会得到以下语句。 即使在Hello world应用程序中,我也得到相同的logcat输出。我没有在我的应用程序中使用多线程。有人能告诉我为什么在我的logcat中得到这些日志。 这是我的密码 在我的异步任务中,我从服务器获取JSONArray,解析它并列出。

  • 我在前台还是个新人。我有一个html页面,我需要分析做我的项目,我不忍心。是Bootstrap吗?}中的那些标记是什么?我在哪里能了解到它?对不起我的英语。谢谢。

  • 我有以下JSON文件,它是通过调用数据流生成的。使用以下代码,我无法打开文件,而是出现以下错误: 我使用了Jsonlint并得到以下错误: 我曾尝试通过pandas打开该文件,但也不起作用。任何帮助都将不胜感激,我不知道如何调试这一点。 输出: