使用Android DefaultHTTPClient执行POST请求会导致执行冻结()

时间:2010-12-01 06:58:21

标签: android

我需要将数据发布到服务器。 我使用这段代码:

HttpClient client = new DefaultHttpClient();
try {

    HttpPost httppost = new HttpPost(serverUrl);

    StringEntity se = new StringEntity(data);
    httppost.setEntity(se);
    httppost.setHeader("Accept", "application/json");
    httppost.setHeader("Content-type", "application/json");

    // Execute HTTP Post Request
    HttpResponse response = client.execute(httppost);
    int statusCode = response.getStatusLine().getStatusCode();
    Log.i(TVProgram.TAG, "ErrorHandler post status code: " + statusCode);

} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (client != null) {
        client.getConnectionManager().shutdown();
    }
}

但问题是Android冻结了execute()方法,应用程序被阻止了,经过一段时间Android告诉我应用程序没有响应。

我尝试调试SDK类,并在第103行的AbstractSessionInputBuffer类中冻结,这是

l = this.instream.read(this.buffer, off, len);

我也尝试过在分离的线程中运行请求,但同样的问题。

我在Android 2.1(模拟器)和Android 2.2真实移动设备上进行了测试 我还尝试设置HTTP代理并使用Fiddler检查服务器和服务器收到的HTTP通信数据也发送正确的答案和HTTP代码200.一切似乎都没问题。

有什么问题?

更新:当我使用AndroidHttpClient时,它是Android 2.2 SDK的一部分,效果很好。但它不是早期版本的Android。所以我现在在我的应用程序中包含它的源代码。但AndroidHttpClient内部使用DefaultHTTPClient,因此DefaultHttpClient的配置会出现问题。

4 个答案:

答案 0 :(得分:0)

我正在成功使用POST HTTP请求。这是我的代码。我使用处理程序删除了部分以显示消息等以及处理程序本身。 POST字符串类似于“& NAME = value @ NAME2 = value2”...

protected class ConnectingThread implements Runnable
{          
    Message msg;
    private Handler mExtHandler;
    private String mData;
    private String mUrl;

    /** 
     * @param h (Handler) - a handler for messages from this thread
     * @param data (String) - data to be send in HTTP request's POST
     * @param url (String) - URL to which to connect
     */
    ConnectingThread(Handler h, String data, String url) {
        mExtHandler = h;
        mData = data;
        mUrl = url;
    }

    public void run() {         
        try {
            // TODO use the handler to display txt info about connection

            URL url = new URL(mUrl);
            URLConnection conn = url.openConnection();             
            conn.setConnectTimeout(CONN_TIMEOUT_MILLIS);

            conn.setDoOutput(true);
            BufferedOutputStream wr = new BufferedOutputStream(conn.getOutputStream());                
            wr.write(mData.getBytes());
            wr.flush();
            wr.close();

            String sReturn = null;

            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            int length = conn.getContentLength();
            char[] buffer = new char[length];
            int read = rd.read(buffer);
            if(read == length)
                sReturn = new String(buffer);
            rd.close();
            buffer = null;   
         // TODO use the handler to use the response

        } catch (Exception e) {
            //....
        }  
        // TODO use the handler to display txt info about connection ERROR   
    }

}           

答案 1 :(得分:0)

client.execute(httppost);不同步吗?

你可能需要将它放在一个线程中,否则它会冻结UI。

答案 2 :(得分:0)

是的,它被冻结只是becoz 您还没有将其实现为异步流程。因为在它发出Web请求时,您的UI将等待响应,然后在收到响应后将更新它。

因此,这应该作为异步流程实现,并且应该通知用户(使用进度条或进度对话框)发生了某些事情。

现在,不是实现Runnable类,而是在android中优先使用并建议使用AsyncTask,它也称为 Painless Threading

  • 您是否在 doInBackground()方法中执行后台任务。
  • onPostExecute()方法中执行显示操作类型,例如使用获取的数据更新listview,在TextViews中显示值等等。
  • onPreExecute()方法中显示ProgressBar或ProgressDialog。

答案 3 :(得分:0)

在这种情况下使用AndroidHttpClient帮助了我。

但是现在完整版AndroidHttpClientDefaultHttpClient在当前版本的Android中已经过时,所以它现在并不重要。