HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议,它是基于TCP/IP协议的应用层协议。主要特点是:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
HTTP/1.1协议中共定义了八种方法(有时也叫“动作”)来表明Request-URI指定的资源的不同操作方式,其中最重要的两种方法是:
1.GET方法 - 向特定的资源发出请求。
2.POST方法 - 向指定资源提交数据进行处理请求(例如提交表单或者上传文件),数据被包含在请求体中。
Android系统中提供了三种通信接口,其中Apache接口是较为常用的。
1.标准Java接口,java.net
2.标准Apache接口,org.apache.http
3.Android网络接口,android.net.http
实例一:使用Java接口的http进行网络通信
①布局文件,一个button,一个ImagevView,点击button后从网络下载一张图片显示在ImageView上。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点击下载图片" />
<ImageView
android:id="@+id/imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/button" />
</RelativeLayout>
②Activity
package com.example.httpgetdemo_apache;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends ActionBarActivity {
private ImageView imageView;
// 百度图片上随便找的一张图片
private static String URL_PATH = "http://pic002.cnblogs.com/images/2011/134595/2011031314373057.png";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageview);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
// 点击button后启动线程,因为主线程上不可以进行网络通信
new Thread(new MyThread()).start();
}
});
}
private class MyThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
URL url;
try {
// url指定为图片地址
url = new URL(URL_PATH);
// 打开网络连接
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
// 设置连接超时时间。HttpUrlConnection对象还有其他的方法也是比较重要的,看下API。
connection.setConnectTimeout(5000);
// 获得Http状态码,200为OK
int response = connection.getResponseCode();
InputStream inputStream = null;
if (response == 200) {
System.out.println("连接成功");
// 获得输入流
inputStream = connection.getInputStream();
} else {
System.out.println("连接异常");
}
// 将输入流转化为Bitmap对象
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
// 通过handler处理来刷新主线程
Message message = Message.obtain();
Bundle data = new Bundle();
data.putParcelable("bitmap", bitmap);
message.setData(data);
handler.sendMessage(message);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// 通过handler处理来刷新主线程
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
Bitmap bitmap = msg.getData().getParcelable("bitmap");
imageView.setImageBitmap(bitmap);
}
};
}
③添加网络权限
<uses-permission android:name="android.permission.INTERNET"/>
实例二: 使用Apache接口的http进行网络通信
①和③和上面一致,直接修改Activity
package com.example.httpgetdemo_apache;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends ActionBarActivity {
private ImageView imageView;
private static String URL_PATH = "http://pic002.cnblogs.com/images/2011/134595/2011031314373057.png";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageview);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
// new Thread(new MyThread()).start();
// 使用异步任务,其实他就是封装好的Thread+Handler
new MyAsynTask().execute();
}
});
}
private class MyAsynTask extends AsyncTask<Void, Void, Bitmap> {
@Override
protected Bitmap doInBackground(Void... arg0) {
// TODO Auto-generated method stub
// 基本上就按照以下流程走就是了
// 实例化HttpClint对象
HttpClient client = new DefaultHttpClient();
// 实例化HttpGet对象,传入URL地址
HttpGet httpGet = new HttpGet(URL_PATH);
Bitmap bitmap = null;
try {
// HttpClint对象的执行方法,参数常用HttpGet、HttpPost对象,
// 返回HttpResponse对象,相当于上面的状态码吧?
HttpResponse response = client.execute(httpGet);
// 通过HttpResponse对象得到实体对象,然后获得输入流,转化为Bitmap对象
HttpEntity entity = response.getEntity();
InputStream inputStream = entity.getContent();
bitmap = BitmapFactory.decodeStream(inputStream);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
// 异步任务就是后台执行完doInBackground方法后,返回一个值,然后onPostExecute方法做处理
super.onPostExecute(result);
// 将返回的Bitmap对象用来显示ImageView
imageView.setImageBitmap(result);
}
}
}
以上两个实例都是使用的Get方法。如果需要向服务器提交数据,Get方法是将数据直接显示地添加到url上,格式就是在原有的url基础上添加?key1=value1&key2=value2;而Post方法在Apache接口中是在HttpPost对象中设置实体,其主要步骤是:
HttpPost httpPost = new HttpPost(URL_PATH);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("name1", "value1"));
nameValuePairs.add(new BasicNameValuePair("name2", "value2"));
HttpEntity entity = new UrlEncodedFormEntity(nameValuePairs);
httpPost.setEntity(entity);
可以看出,使用Post方法提交数据是比Get方法安全的。由于自己不懂搭建服务器,所以这个有点不好测试,先留个印象吧!