1

我正在开发一个执行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;
}       
}

我的问题是,我如何JSONObject从这个新的AsyncTask类中返回一个?我可以看到它jObj正在被返回doInBackground(),但我不确定它被返回到哪里。

我需要修改什么或者我需要如何调用我的新JSONParser类以便它返回一个JSONObject

4

4 回答 4

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());
        }       
    }
}
于 2013-04-12T05:02:29.077 回答
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(); 

在你的异步任务中;

String url;
List<NameValuePair> params;

// constructor
public JSONParser(String url, List<NameValuePair> params) {
this.url = url;
this.params = params;
}
于 2013-04-12T04:42:25.927 回答
0

从你的doInBackground方法

@Override
protected JSONObject doInBackground(String... args) {

 return jObj;

}

你的JsonObject回报

@Override
protected void onPostExecute(JSONObject jObj) {

    // Here you get your return JsonObject
}  
于 2013-04-12T04:47:25.567 回答
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.

您需要了解的一点是,您在调用时正在创建 Async Task Class 的对象new JSONParser(loginURL, params);

解决方案是在您的 Async 类中创建一个公共结果变量并调用execute()类的对象,然后从该对象访问公共对象。

于 2013-04-12T04:52:30.157 回答