尝试在asyncTask里的doInBackground方法中执行asyncHttp请求的时候会报如下异常:Caused by: java.lang.IllegalArgumentException: Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.
async http本身属于异步操作,异步做完耗时的网络请求操作之后就要用回调实现数据在主线程中的填充,这个回调的实现原理就是通过子线程的handler和主线程之间完成的异步交互。而asyncTask本身也是异步的,async http的回调肯定是要在主线程实现的,而如果试图在asyncTask的doInbackGround即子线程中执行就肯定会出错。所以,异步操作是不可以在其他异步操作的子线程中执行的,这样做也是没有意义的。
从另一个角度来说,async http 和httpClient的区别就在于async http是内部实现异步操作的,即async http自动实现网络请求的操作在子线程执行,而请求的结果处理需要我们通过AsyncHttpResponseHandler 里面的回调方法去实现,这几个方法我们是需要主线程实现的,因为async http内部已经通过handler机制实现了子线程与主线程的通信。而httpClient是需要我们主动实现子线程,然后把httpClient的请求操作放入子线程,比如下面两种方式他们的实质效果是一样的:
1.主动创建子线程实现异步请求:
new Thread(new Runnable() {
@Override
public void run() {
//Url
String Url = "http://ubs.free4lab.com/php/method.php";
//请求参数封装
List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();
params.add(new BasicNameValuePair("user_id", "123456"));
params.add(new BasicNameValuePair("user_name", "erBi"));
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost();
post.setEntity(new UrlEncodedFormEntity(params,"utf-8"));
HttpResponse response = client.execute(post); //获取请求的返回对象
int code = response.getStatusLine().getStatusCode(); //获取响应的code
String result = EntityUtils.toString(response.getEntity(),"utf-8"); //获取响应的实体并解析成字符串
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
2.使用asyncTask实现异步请求:
class MyAsyncHttp extends AsyncTask<Integer, Integer, String>{
@Override
protected String doInBackground(Integer... params) {
//Url
String Url = "http://ubs.free4lab.com/php/method.php";
//请求参数封装
List<BasicNameValuePair> requestParams = new LinkedList<BasicNameValuePair>();
requestParams.add(new BasicNameValuePair("user_id", "123456"));
requestParams.add(new BasicNameValuePair("user_name", "erBi"));
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost();
post.setEntity(new UrlEncodedFormEntity(requestParams,"utf-8"));
HttpResponse response = client.execute(post); //获取请求的返回对象
int code = response.getStatusLine().getStatusCode(); //获取响应的code
String result = EntityUtils.toString(response.getEntity(),"utf-8"); //获取响应的实体并解析成字符串
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
上述两种异步请求的实质是一样的,区别是异步线程是自己主动创建还是API中已经实现了的,我们只需要实现对应借口方法即可。而async http就更牛逼一些,它是已经实现了异步的请求,等于是以上两步(请求、异步)的综合,说到这应该很明白了吧。所谓格物致知,我们搞清楚事物的本质,就自然明白因果对错。
而如果真的遇到需要在子线程过程中的某个点调用async http请求方法情况,可以用sendMessage通知主线程去执行异步请求,或者直接用handler.post把异步操作直接放入主线程执行。
补充一点本人初学时候容易混淆的网络概念方面的小知识:
java中两种基本的网络请求api:
1.阿帕奇提供的api
HttpClient //org.apache.http.client.HttpClient
2.java原生api
HttpURLConnection //java.net.HttpURLConnection
3.async-http第三方:
是基于HttpClient封装出来的一个异步请求第三方网络框架