我正在开发一个执行 http POST请求的Android应用程序,我所遵循的教程产生了android.os.NetworkOnMainThreadException
原始代码是这样的。
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// 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());
}
// return JSON String
return jObj;
}
}
用这一行调用了这个类。
JSONObject json = jsonParser.getJSONFromUrl(loginURL, params);
将此更改为AsyncTask类后,代码如下所示。
class JSONParser extends AsyncTask<String, Void, JSONObject>{
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// variables passed in:
String url;
List<NameValuePair> params;
// constructor
public JSONParser(String url, List<NameValuePair> params) {
this.url = url;
this.params = params;
}
@Override
protected JSONObject doInBackground(String... args) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// 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());
}
// return JSON String
return jObj;
}
@Override
protected void onPostExecute(JSONObject jObj) {
return;
}
}
我的问题是,如何从这个新的 AsyncTask 类中返回JSONObject
?我可以看到jObj
中正在返回doInBackground()
,但是我不知道它在哪里归还。
我需要修改哪些内容,或者如何调用我的新JSONParser
课程,以便它返回JSONObject
?
答案 0 :(得分:1)
看看这段代码,它可以让你深入了解如何处理JSON对象的解析。我现在只是发布了onPostExecute函数,因为你似乎已经正确地计算了所有其他函数。
至于你对doInBackground中的数据对象返回的位置存在疑问,它会自动发送到onPostExecute,您可以在其中进一步解析它。
@Override
protected void onPostExecute(JSONObject result)
{
try
{
JSONObject data = result.getJSONObject("data");
// whatever your JSON tag may be, in this case its data.
if (data.isNull("data"))
{
// action to handle null JSON object.
}
else
{
JSONArray jarray = data.getJSONArray("data");
int len=jarray.length();
for (int i = 0; i < jarray.length(); i++)
{
JSONObject obj = (JSONObject) jarray.get(i);
String instanceName = obj.getString("instanceName");
//extract data by whatever tag names you require, in this case instanceName.
}
}
}
catch (JSONException je)
{
je.printStackTrace();
Log.d(TAG, "Error: " + je.getMessage());
}
}
}
答案 1 :(得分:0)
我可以看到jObj正在doInBackground()中返回,但我不是 确定它返回的位置。
doinBackground()的结果作为onPostExecute()中的参数被接收。您将在doinBackground()中返回一个json对象,该对象是onPostExecute()的参数。
@Override
protected void onPostExecute(JSONObject jObj) {
return;
}
用法
new JSONParser().execute("url);
class JSONParser extends AsyncTask<String, Void, JSONObject>{
//string parameter to doInBackground()
//JSONObject - result returned in doInBackground() received as a param in onPostExecute()
}
您还可以将参数传递给asynctask的构造函数
new JSONParser("url",params).execute();
在你的asynctask;
String url;
List<NameValuePair> params;
// constructor
public JSONParser(String url, List<NameValuePair> params) {
this.url = url;
this.params = params;
}
答案 2 :(得分:0)
来自doInBackground
方法
@Override
protected JSONObject doInBackground(String... args) {
return jObj;
}
您将JsonObject
返回
@Override
protected void onPostExecute(JSONObject jObj) {
// Here you get your return JsonObject
}
答案 3 :(得分:0)
异步任务有3个属性
Params, the type of the parameters sent to the task upon execution.
Progress, the type of the progress units published during the background computation.
Result, the type of the result of the background computation.
您需要了解的一点是,您在调用new JSONParser(loginURL, params);
时正在创建异步任务类的对象
解决方案是在Async类中创建一个公共结果变量,在类的对象上调用execute()
,然后从该对象访问公共对象。