[英]Android Parse JSON stuck on get task
I am trying to parse some JSON data. 我正在尝试解析一些JSON数据。 My code was working for awhile, and I am not sure what I changed to suddenly break the code. 我的代码工作了一段时间,我不确定为突然破坏代码所做的更改。 When I run my code I am not receiving any runtime errors or warnings. 运行代码时,我没有收到任何运行时错误或警告。 I create a new AsyncTask and execute this. 我创建一个新的AsyncTask并执行它。 When I call .get()
on this new task, the debugger stalls on this line and takes more than 30 minutes. 当我在此新任务上调用.get()
时,调试器将在此行停顿并花费30多分钟。 I have not been able to get the debugger or during run to complete this task. 我无法获得调试器或在运行期间无法完成此任务。
JSON: JSON:
protected void setUp(Context context) {
_context = context;
getConfig();
}
// get config file
protected void getConfig() {
if (config != null)
return;
config = new Config();
String url = configURL;
AsyncTask<String, Integer, JSONObject> jsonTask = new DownloadJSONTask()
.execute(url);
JSONObject configItem = null;
try {
configItem = jsonTask.get(); //debugger pauses here
if (configItem == null)
return;
config.configVersion = configItem.getString("field_configversion");
config.currentAppVersion = configItem
.getString("field_currentappversion");
config.getSupportURL = configItem.getString("field_getsupporturl");
config.getCatalogURL = configItem.getString("field_getcatalogurl");
config.getDataVersion = configItem.getString("field_dataversion");
config.getDataUrl = configItem.getString("field_dataurl");
config.getDataApiKey = configItem.getString("field_dataapikey");
} catch (InterruptedException e) {
e.printStackTrace();
System.err.println("Download of config interrupted");
} catch (ExecutionException e) {
e.printStackTrace();
System.err.println("Download of config failed to execute");
} catch (JSONException e) {
e.printStackTrace();
}
cacheStaticData(_context);
}
DownloadJSONTask.java 下载JSONTask.java
package com.example.simplegraph;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.os.AsyncTask;
public class DownloadJSONTask extends AsyncTask<String, Integer, JSONObject> {
private HttpClient client = new DefaultHttpClient();
private HttpGet request;
private HttpResponse response;
DownloadJSONTask() {
super();
}
// tries to grab the data for a JSONObject
@Override
protected JSONObject doInBackground(String... urls) {
request = new HttpGet(urls[0]);
try {
response = client.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String result = convertStreamToString(instream);
JSONObject json = new JSONObject(result);
instream.close();
return json;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
// converts the InputStream to a string and add nl
private String convertStreamToString(InputStream is) {
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
is.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
return sb.toString();
}
}
And HomeActivity.java 还有HomeActivity.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
new AddStringTask().execute();
}
class AddStringTask extends AsyncTask<Void, String, Void> {
@Override
protected Void doInBackground(Void... unused) {
app = (EconApplication) getApplication();
getApp().setUp(HomeActivity.this);
HomeActivity.this.setUpDrawer();
return (null);
}
@Override
protected void onPostExecute(Void unused) {
setUpDataDisplay();
setUpGraphRange();
createTable();
createGraph(-1);
}
}
QUESTION: Why is my code getting stuck on .get()? 问题:为什么我的代码卡在.get()上?
You can greatly simplify everything using the droidQuery library: 您可以使用droidQuery库大大简化一切:
$.getJSON("http://www.example.com", null, new Function() {//this will run using an AsyncTask, get the JSON, and return either a JSONObject or JSONArray on the UI Thread.
@Overrde
public void invoke($ droidQuery, Object... params) {
if (params[0] instanceof JSONObject) { //it's often ok just to assume a JSONObject, making your first line simply: JSONObject obj = (JSONObject) params[0];
//JSONObject is returned
JSONObject json = (JSONObject) params[0];
//to easily parse this Object, convert it to a map first:
Map<String, ?> map = $.map(json);
//then you can just make a call like this:
if (map.contains("field_currentappversion")) {
config.currentAppVersion = (String) map.get("field_currentappversion");
}
}
else {
//JSONArray is returned
JSONArray json = (JSONArray) params[0];
//if you got an array, you can easily convert it to an Object[] for parsing:
Object[] array = $.makeArray(json);
}
}
});
AsyncTask.get()
blocks the caller thread. AsyncTask.get()
阻止调用者线程。 Use AsyncTask.execute()
instead. 请改用AsyncTask.execute()
。
public final Result get ()
Added in API level 3 在API级别3中添加
Waits if necessary for the computation to complete, and then retrieves its result. 必要时等待计算完成,然后检索其结果。
Returns The computed result. 返回值计算结果。
Drawing from 从中绘图
How do I return a boolean from AsyncTask? 如何从AsyncTask返回布尔值?
Try the below 试试下面
new DownloadJSONTask(ActivityName.this).execute(url);
In your DownloadJSONTask 在您的DownloadJSONTask中
In the construcotr 在建筑中
TheInterface listener;
public DownloadJSONTask(Context context)
{
listener = (TheInterface) context;
}
Interface 接口
public interface TheInterface {
public void theMethod(ArrayList<String> result); // your result type
}
In your doInbackground
return the result. 在您的doInbackground
返回结果。 I am assuming its ArrayList of type String. 我假设它的ArrayList是String类型。 Change the arraylist to what suits your requirement. 将arraylist更改为适合您的要求。
In your onPostExecute
在你的onPostExecute
if (listener != null)
{
listener.theMethod(result); // result is the ArrayList<String>
// result returned in doInbackground
// result of doInbackground computation is a parameter to onPostExecute
}
In your activity class implement the interface 在活动类中实现接口
public class ActivityName implements DownloadJSONTask.TheInterface
Then 然后
@Override
public void theMethod(ArrayList<String> result) { // change the type of result according yo your requirement
// use the arraylist here
}
Edit: Alternative 编辑:替代
You can makes your asynctask an inner class of your activity class. 您可以将asynctask设为活动类的内部类。 The result on doInbackground
computation is a parameter to onPostExecute
. 在结果doInbackground
计算是一个参数onPostExecute
。 Return result in doInbackground
. 在doInbackground
返回结果。 Update ui in onPostExecute
. 在onPostExecute
更新ui。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.