我正在尝试制作一个从 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
的参数:
- 此类型是提供给
doInBackground
的参数类型 - 此类型用于显示进度条,例如,如果您下载了很多内容,您可以覆盖名为
onProgressUpdate
的函数,并可以显示您的应用上已经下载了多少内容,以便用户知道某事正在发生。 - 此类型是
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/