一、HTTP协议初探:
HTTP(Hypertext Transfer Protocol)中文 “超文本传输协议”,是一种为分布式,合作式,多媒体信息系统服务,面向应用层的协议,是Internet上眼下使用最广泛的应用层协议。它基于传输层的TCP协议进行通信,HTTP协议是通用的、无状态的协议。
这几个名词有一种通俗的解释:
- 通讯协议:两方对话的标准
- 通用的:用了都说好,谁用谁知道
- 无状态的:翻脸不认人
- 超文本:除了文本,还能够是音频、视频
HTTP协议与Android开发之间的关系:
HTTP协议的学习重点:
- Http协议基础概念、
- 请求响应模型、
- 提交请求的不同方法、
- 响应状态推断、
- 获取响应以及解析响应、
- 数据下载的实现方法、
- 数据上传的实现方法、
- 请求头具体内容、
- 响应头具体内容等
WWW的工作是基于客户机/server计算模型,由Web浏览器和Webserver构成,两者之间採用超文本传输协议HTTP进行通信。
- 第一:浏览器和server是通过什么来连接的。
- 第二:这样的连接方式是怎么实现的。
- 第一种:HTTP协议。也是在工作中最经常使用的。是建立在TCP/IP基础上实现的。
- 另外一种:FTP协议
- 第三种:TCP/IP协议,它也是最底层的协议族。其他的方式必须是要通过它,可是要想实现这样的协议必需要实现socket编程,这样的方法是用来上传一些比較大的文件,视频,进行断点续传的操作。
- 第一步:在浏览器client中得到用户输入的内容。
- 第二步:浏览器得到这个网址之后。内部会将这个域名发送到DNS上,进行域名解析。得到它的IP之后就会链接到指定的server上,假如server的地址是:221.104.13.32:80。从浏览器到serverport它使用到最底层的TCP/IP协议。
- 第三步:实现TCP/IP协议用Socket来完毕。使用了Socket的套接字。
- 第四步:server端的80port监听client的链接,这样client到server就链接上了。
- server接收到这些内容之后。并依照这些请求的路径找到相应的页面,进一步找到相应的网页内容,返回给client。
- 1、以HTML代码内容返回。
- 2、以XML字符串的形式返回,在android开发中这样的形式返回数据比較多。
- 3、以JSON对象形式返回,在网络流量上考虑JSON要比XML方式要好一些,便于解析。
三、使用HTTP协议訪问网络:
Android中的WebView控件已经在后台帮我们处理好了发送HTTP请求、接收服务响应、解析返回数据,以及终于的页面展示这几步工作,只是因为它封装得太好了,反而不能直观地看出HTTP协议是怎样工作的。因此接下来我们通过手动发送HTTP请求的方式。来更加深入的了解这一过程。
在Android上发送HTTP请求的方式一般有两种:HttpURLConnection和HttpClient。
我们先来学习HttpClient。
四、HttpCient:
HttpClient是Apache开源组织提供的HTTP网络訪问接口(一个开源的项目)。从名字上就能够看出。它是一个简单的HTTPclient(并非浏览器)。能够发送HTTP请求,接受HTTP响应。可是不会缓存server的响应。不能运行HTTP页面中签入嵌入的JS代码,自然也不会对页面内容进行不论什么解析、处理,这些都是须要开发者来完毕的。
如今Android已经成功集成了HttpClient,所以开发者在Android项目中能够直接使用HttpClient来向Web网站提交请求以及接受响应,假设使用其它的Java项目,须要引入进对应的Jar包。HttpClient能够在官网上下载。
官网链接:http://hc.apache.org/downloads.cgi
HttpClient事实上是一个interface类型,HttpClient封装了对象须要运行的Http请求、身份验证、连接管理和其他特性。
既然HttpClient是一个接口,因此无法创建它的实例。从文档上看。HttpClient有三个已知的实现类各自是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也能够实现功能。
从两个类包全部在位置就能够看出差别,AndroidHttpClient定义在android.net.http.AndroidHttpClient包下,属于Android原生的http訪问。而DefaultHttpClient定义在org.apache.http.impl.client.DefaultHttpClient包下,属于对apche项目的支持。而AndroidHttpClient没有公开的构造函数,仅仅能通过静态方法newInstance()方法来获得AndroidHttpClient对象。
简单来说,用HttpClient发送请求、接收响应都非常easy,仅仅须要五大步骤就可以:(要牢记)
- 创建代表client的HttpClient对象。
- 创建代表请求的对象,假设须要发送GET请求,则创建HttpGet对象,假设须要发送POST请求。则创建HttpPost对象。
注:对于发送请求的參数,GET和POST使用的方式不同。GET方式能够使用拼接字符串的方式。把參数拼接在URL结尾。POST方式须要使用setEntity(HttpEntity entity)方法来设置请求參数。
- 调用HttpClient对象的execute(HttpUriRequest request)发送请求,运行该方法后,将获得server返回的HttpResponse对象。server发还给我们的数据就在这个HttpResponse响应其中。调用HttpResponse的相应方法获取server的响应头、响应内容等。
- 检查对应状态是否正常。server发给client的相响应,有一个响应码:响应码为200。正常;响应码为404,client错误。响应码为505,server端错误。
- 获得响应对象其中的数据
五、DefaultHttpClient:
依据上面的五大步骤,我们就拿DefaultHttpClient举例来訪问网络。
注意这里有一条原则:在主线程中不能訪问网络(在android4.0之后的增加的概念)。
一个demo:点击button,获取百度首页的文本内容
新建project文件m04_http01。
完整版代码例如以下:
首先是布局文件。尽管比較简单。但还是贴上吧。
activity_main.xml代码例如以下:
<LinearLayout 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" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Send Request" /> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:id="@+id/TextView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello_world" /> </ScrollView> </LinearLayout>
布局文件里,我们用一个ScrollView来包裹TextView。借助ScrollView控件的话。就能够同意我们一滚动的形式查看屏幕外i的那部分内容。
MainActivity.java的代码例如以下:(凝视比較具体)
package com.example.m04_http01; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { public static final int SHOW_RESPONSE = 0; private Button button_sendRequest; private TextView textView_response; //新建Handler的对象,在这里接收Message。然后更新TextView控件的内容 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case SHOW_RESPONSE: String response = (String) msg.obj; textView_response.setText(response); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView_response = (TextView)findViewById(R.id.TextView1); button_sendRequest = (Button)findViewById(R.id.button1); button_sendRequest.setOnClickListener(new OnClickListener() { //点击按钮时。运行sendRequestWithHttpClient()方法里面的线程 @Override public void onClick(View v) { // TODO Auto-generated method stub sendRequestWithHttpClient(); } }); } //方法:发送网络请求,获取百度首页的数据。在里面开启线程 private void sendRequestWithHttpClient() { new Thread(new Runnable() { @Override public void run() { //用HttpClient发送请求,分为五步 //第一步:创建HttpClient对象 HttpClient httpCient = new DefaultHttpClient(); //第二步:创建代表请求的对象,參数是訪问的server地址 HttpGet httpGet = new HttpGet("http://www.baidu.com"); try { //第三步:运行请求,获取server发还的响应对象 HttpResponse httpResponse = httpCient.execute(httpGet); //第四步:检查响应的状态是否正常:检查状态码的值是200表示正常 if (httpResponse.getStatusLine().getStatusCode() == 200) { //第五步:从对应对象其中取出数据。放到entity其中 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity,"utf-8");//将entity其中的数据转换为字符串 //在子线程中将Message对象发出去 Message message = new Message(); message.what = SHOW_RESPONSE; message.obj = response.toString(); handler.sendMessage(message); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start();//这个start()方法不要忘记了 } }
最后要记得在清单文件里声明訪问网络的权限:
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" /> <uses-permission android:name="android.permission.INTERNET"/>程序执行后,点击button,显示结果例如以下:
关于http协议的学习,推荐两个链接:
http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html
http://blog.csdn.net/gueter/article/details/1524447