使用POST异步发送JSON对象(android.os.NetworkOnMainThreadException)

时间:2014-04-20 15:27:10

标签: java android post

我正在尝试使用http POST方法将JSON发送到Web服务。另外我试图让它异步,所以它在Android设备上的后台线程中运行。

我的问题是:

我想让这个类通用,所以我可以发送任何JSON对象。我为sendHTTPData添加了另一个参数(String url,JSONObject json)。为了在后台线程中运行,我必须显式覆盖doInBackground。

如果我显式覆盖doInBackground,我如何将我的JSON对象传递给这个泛型方法。

当我自己运行sendHTTPData时,我得到android.os.NetworkOnMainThreadException。

代码:

    public class SendHttpDataAsync extends AsyncTask<String, Void,  String> {
    private static final String TAG = "SendHttpDataAsync";

    @Override
    protected String doInBackground(String... urls) {
        return sendHTTPData(urls[0], MY_JSON_OBJECT);
    }

    public String sendHTTPData(String url, JSONObject json) {
        HttpURLConnection connection = null;
        try {
            URL object=new URL(url);
            connection = (HttpURLConnection) object.openConnection();

            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Accept", "application/json");

            OutputStreamWriter streamWriter = new OutputStreamWriter(connection.getOutputStream());

            streamWriter.write(json.toString());
            streamWriter.flush();

            StringBuilder stringBuilder = new StringBuilder();

            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK){
                InputStreamReader streamReader = new InputStreamReader(connection.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(streamReader);

                String response = null;
                while ((response = bufferedReader.readLine()) != null) {  
                    stringBuilder.append(response + "\n");  
                }  
                bufferedReader.close();  

                Log.d(TAG, stringBuilder.toString());
                return stringBuilder.toString();
            } else {
                Log.e(TAG, connection.getResponseMessage());
                return null;
            }   
        } catch (Exception exception){
            Log.e(TAG, exception.toString());
            return null;
        } finally {
            if (connection != null){
                connection.disconnect();
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

实际上,您没有在doInBackground()方法中运行任何内容,而这是唯一一种在主UI上{<>> 调用的方法Thread { 1}}。这意味着您必须在doInBackground()内调用您的网络方法,否则您将获得NetworkOnMainException

----编辑----

要将一些参数传递给AsyncTask,请执行以下操作:

  1. AsyncTask<String, Void, String>替换为AsyncTask<JSONObject, Void, String>。这样,您就可以说doInBackground()中的参数是JSONObject

  2. 现在,您的doInBackground()方法会包含以下参数:doInBackground(JSONObject... params)

  3. 以这种方式获取您传递给方法的参数:

    @Override
    protected String doInBackground(JSONObject... params) {
      JSONObject myJsonObject = params[0];
      sendHTTPData(url, myJsonObject);
    }
    
  4. 现在只需按此方式拨打AsyncTask

    SendHttpDataAsync at = new SendHttpDataAsync();
    at.execute(myJsonObject);