java - 当JSON文件没有任何且只有获取对象时如何创建数组

标签 java android arrays json android-asynctask

我正在尝试制作一个从 Android 上的 url 获取数据的应用程序。我注意到 JSON 文件是不同的。其中一些以 Arrach 名称开头,有些则不是。那些具有数组名称 like this 的数组其中“user”是数组名称,在我的应用程序中工作,但那些没有任何数组名称的应用程序不起作用。 For example this .

这是我尝试将数组设为对象的代码,但它不适用于第二个 JSON 文件,因为它找不到数组名称:

//URL to get JSON Array
private static String url = "http://api.worldbank.org/countries/ir?format=json";

//JSON Node Names 
private static final String TAG_USER = "user";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";

JSONArray user = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    // Creating new JSON Parser
    JSONParser jParser = new JSONParser();

    // Getting JSON from URL
    JSONObject json = jParser.getJSONFromUrl(url);

    try {
        // Getting JSON Array
        user = json.getJSONArray(TAG_USER);
        JSONObject c = user.getJSONObject(0);

        // Storing  JSON item in a Variable
        String id = c.getString(TAG_ID);
        String name = c.getString(TAG_NAME);
        String email = c.getString(TAG_EMAIL);

        //Importing TextView
        final TextView uid = (TextView)findViewById(R.id.uid);
        final TextView name1 = (TextView)findViewById(R.id.name);
        final TextView email1 = (TextView)findViewById(R.id.email);

        //Set JSON Data in TextView
        uid.setText(id);
        name1.setText(name);
        email1.setText(email);

} catch (JSONException e) {
    e.printStackTrace();
}

}

所以这个示例适用于第一个 JSON 部分。您能告诉我如何获得第二个 JSON 文件的类似代码吗?

最佳答案

因此,首先您不允许在主线程上执行网络操作,因为这些操作往往需要很长时间(如果服务器没有响应或连接不良或您尝试获取的文件很大)如果在主线程上完成,它将阻止手机上的应用程序。如果您的应用程序长时间没有响应,它将被 Android 操作系统自动终止。为了避免这种情况,您需要使用 AsyncTasks。这些任务可以在后台工作,同时主线程仍在响应用户输入。

您可以阅读有关 AsyncTasks 的更多信息 here .

[编辑] 因此,回答您对问题的评论:您收到 NetworkOnMainThreadException 的原因是因为您在主线程(您在主线程中调用 jParser.getJSONFromUrl(url); )正常执行代码)。不允许这样做的原因是,在方法 getJSONFromUrl() 中,您发出 HTTP 请求,并且必须等待来自给定 URL 的响应。正如我上面所解释的,这可能需要很长时间,并且会阻止您在手机上的应用程序,并产生已经解释过的后果。现在要解决这个问题,您需要执行以下操作:

之前(不好):

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// Creating new JSON Parser
JSONParser jParser = new JSONParser();

// Getting JSON from URL
JSONObject json = jParser.getJSONFromUrl(url);

// get the data from your JSONObject

}

更好:

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// Getting JSON from URL
new JsonRequest().execute(url);

}

private class JsonRequest extends AsyncTask<String, Void, JSONObject>
// I will talk about the parameters to AsyncTask below
    @Override
    protected JSONObject doInBackground(String... urls) {
        // Creating new JSON Parser
        JSONParser jParser = new JSONParser();

        // Getting JSON from URL
        JSONObject json = jParser.getJSONFromUrl(url);

        return json;
    }


    @Override
    protected void onPostExecute(JSONObject result) {

        // Get the array
        JSONArray array = result.getJSONArray("data");

        // Display the data
        // Import textviews
        // and so on..
    }

现在了解AsyncTask的参数:

  1. 此类型是提供给 doInBackground 的参数类型
  2. 此类型用于显示进度条,例如,如果您下载了很多内容,您可以覆盖名为 onProgressUpdate 的函数,并可以显示您的应用上已经下载了多少内容,以便用户知道某事正在发生。
  3. 此类型是 doInBackground 将返回的类型,并且 onPostExecute 将其作为参数。

这样你的主线程将继续运行,用户不会注意到后台正在进行下载,因为它是一个正在运行的单独任务。我希望这已经很清楚了,如果没有,请留下另一条评论,我会解释更多。 :)

[\编辑]

那么第二个问题是 learn2crack 中的 JSONParser 无法解析 JSONArrays,换句话说,函数 getJSONFromUrl() 只是尝试创建一个新的 JSONObject 来自它从给定 url 获取的 String

基本上有几种方法可以解决这个问题,我做了一些修改(它涉及很少的代码,但之后您将需要更多时间来获取数据)。我将以下几行添加到 getJSONFromUrl() 方法中:

if (json.startsWith("[")) {
    // We have a JSONArray
    try {
        jObj = new JSONObject();
        jObj.put("data", new JSONArray(json));
    } catch (JSONException e) {
        Log.d("JSON Parser", "Error parsing JSONArray " + e.toString());
    }
    return jObj;
}

这些行应添加到此部分的正上方:

// try parse the string to a JSON object
try {
    jObj = new JSONObject(json);
} catch (JSONException e) {
    Log.e("JSON Parser", "Error parsing data " + e.toString());
}

基本上,您最终会得到的是,您可以简单地在任何网址上调用 getJSONFromUrl() ,如果它包含 JSONObject 您将获得该对象,但如果它包含 JSONArray,您将获得一个 JSONObject,其中包含一个名为 data 的字段,其中将包含您的 JSONArray 。所以你可以这样做:

JSONObject json = jParser.getJSONFromUrl(url);

JSONArray array = json.getJSONArray("data");

然后你就有了你的数组(当然,周围有一个 JSONException 的 try catch)。

关于java - 当JSON文件没有任何且只有获取对象时如何创建数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20151397/

相关文章:

arrays - 从 Powershell 使用数组参数调用构造函数

c++ - 如何从 C++ 中的文件中读取乘法字符数组

java - 如何画一条有方向、固定长度的线

java - JDBC动态查询,如果不是-1则只将值写入字符串

java - 创建实例时出现空指针异常

android - 在 Android 中没有 Activity 的情况下刷新服务中的 Azure 用户 token

android - 使用 android gradle 插件运行 aapt

java - 如何在java中从键盘输入一些单词

android - 使用最新版本的 Firebase list 合并失败

c++ - 使用构造函数初始化数组(C++)