如题,android网络框架年年有新,层出不穷。对于初学者来讲,先学会一种的基本用法就够了,能实现前后端的数据交互就够了。没必要浪费太多精力。本文就以最普通的框架HttpClient+HttpPost来实现android开发中与后端Post交互,而且是同步和异步两种实现的最精简方法(尽可能一句非必要的代码都没有,做到最精简。具体有特别的要求,再自行添加相应的配置语句)。
要点:利用thread.join来实现同步
优点:逻辑清晰,没有嵌套。
缺点:只能用于数据交互,不能实现在接收到数据后动态更新UI。而且可能影响正常的UI渲染
public String connect(final String filePath, final String...pairs){//filePath:后端文件的URL,pairs:POST传输的键值数组,偶数下标为键,奇数下标为值
if(pairs == null || pairs.length == 0 || pairs.length%2 != 0){
Log.e("MyError","键值对数量有误");
return null;
}
final String[] result = {null};//用于记录从后端返回的字符串
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
HttpPost post = new HttpPost(filePath);
if(filePath == null || post == null){
Log.e("MyError","filePath有误");
}
else{
//将键值对加入pairs2
List pairs2 = new ArrayList<>();
for(int i = 0; i < pairs.length; i+=2){
pairs2.add(new BasicNameValuePair(pairs[i],pairs[i+1]));
}
HttpClient client = new DefaultHttpClient();
try {
HttpResponse response = client.execute(post);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//进行UTF_8解码,并且把可能由于BOM编码而导致的字符串前面有\r\n字符干扰给消除
result[0] = EntityUtils.toString(response.getEntity(),HTTP.UTF_8).replaceAll("\\r\\n","");
}
//返回空字符也与访问失败相同对待
if(result[0] != null && result[0].length() == 0){
result[0] = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result[0];
}
如果要解析JSON数据什么的,再进行一层包装就OK了。利用了thread.join()方法,使得这个方法使用起来完全可以当做同步方法来使用,不需要什么回调函数。
但很多时候,我们需要的不是这么简单直接的同步方法,我们需要更新UI,这时只能利用Handler来更新UI,因此handler就可以当做我们的回调
优点:因为使用了Handler消息处理机制,可以异步更新UI。也可以利用多层Handler多层包装返回的结果
缺点:层次过多时,容易出现嵌套杂乱,逻辑不清晰,可读性差。
public void connect(final String filePath, Handler handler,final String...pairs){//filePath:后端文件的URL,pairs:POST传输的键值数组,偶数下标为键,奇数下标为值
//handler:由调用出传入的handler对象,用于更新UI
if(pairs == null || pairs.length == 0 || pairs.length%2 != 0){
Log.e("MyError","键值对数量有误");
return;
}
final String[] result = {null};//用于记录从后端返回的字符串
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
HttpPost post = new HttpPost(filePath);
if(filePath == null || post == null){
Log.e("MyError","filePath有误");
}
else{
//将键值对加入pairs2
List pairs2 = new ArrayList<>();
for(int i = 0; i < pairs.length; i+=2){
pairs2.add(new BasicNameValuePair(pairs[i],pairs[i+1]));
}
HttpClient client = new DefaultHttpClient();
try {
HttpResponse response = client.execute(post);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//进行UTF_8解码,并且把可能由于BOM编码而导致的字符串前面有\r\n字符干扰给消除
result[0] = EntityUtils.toString(response.getEntity(),HTTP.UTF_8).replaceAll("\\r\\n","");
}
//返回空字符也与访问失败相同对待
if(result[0] != null && result[0].length() == 0){
result[0] = null;
}
//********重点在这里***********
//这里创建一个消息,把从后端返回的结果放到message的obj成员中发送。
Message message = new Message();
message.obj = result[0];
handler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
thread.start();//因为这是异步的,所以不要再使用join了
}
使用该方法很简单,在需要更新UI的地方调用
connect(filePath, new Handler(getMainLooper()){
@Override
public void handleMessage(Message msg) {
String result = msg.obj;
//可对result进行进一步包装,比如如果是JSON字符串可以先转换为JSONArray或JSONObject
//利用result更新你的UI
}
},pairs);
完工!同步异步按需使用,各有优劣。