好吧,首先承认这么晚了写博客我是拒绝的,不能你让我写我就写。但是深思熟虑之后,我还是决定要在每次学习并且实践完后写一篇博客记载一下学习心得。
这次学习的是Android中的HTTP部分,当然还没学完还有一小部分,明日再写。(话说起来,明天和妹纸去看电影,我得抓紧时间写完早点睡觉,就不废话了)
啊,回归正题
http中,首先明确的是tcp/ip协议和http协议。
http协议又分为http1.0和1.1,目前大多数采用1.1.
一个http请求称为一个事务,工作过程分为四步:
1客户与服务器建立连接,只需要客户点击某个超链接即可
2连接成功后,客户向服务器发送一个请求,请求的格式为 统一资源标识符(URL),协议版本号,后面是MIME信息,包括请求修饰符,客户机信息和可能的内容
3服务器接到请求后,会响应一个信息,其格式为一个状态行,包括信息的协议版本号,一个成功或错误的返回码(200表示OK),后面是MIME信息。
4客户机收到信息后显示在屏幕上,然后这次HTTP连接就断开了
HTTP协议的特点就是 客户服务器模式,简单地说就是请求与响应,每次都是客户主动请求信息,服务器被动的响应信息。
TCP/IP协议又有一个三次握手协议
第一次 客户机发送给服务器一个信息 这是第一次握手
第二次 服务器接收到信息后,知道了客户机能给服务器发送消息,于是服务器又给客户机返回一个ASK信息,第二次握手
第三次,客户机收到了消息后,知道了自己发送的消息能被服务器接收到,并且再次把ASK发送给服务器,这次服务器接收到ASK消息后,知道了客户机能收到自己发送的消息
至此,三次握手完成。三次握手的意义在于让客户机和服务器都能明确的知道对方能接受自己发送的信息,这就是一个可靠地连接。
HTTP协议中。请求方式分为GET和POST两种
GET: 请求的信息全部追加到URL后,特点是方便快捷, 缺点是不安全
POST:请求信息不会出现在URL上,以加密的方式进行传输 优点是安全 缺点是不够快捷
Android中提供了两个类来进行GET和POST请求,分别为HttpUrlConnection和HttpClient(在高版本中的API中已经废弃);
httpurlconnection使用方式如下
get:
URL url=new URL(httpurl);
HttpURLConnection coon= (HttpURLConnection) url.openConnection();
coon.setRequestMethod("GET");
coon.setReadTimeout(5000);
BufferedReader bf=new BufferedReader(new InputStreamReader(coon.getInputStream()));
String str;
StringBuffer sb=new StringBuffer();
while((str=bf.readLine())!=null){
sb.append(str);
}
Log.i("test",sb.toString());
POST:
URL url=new URL(httpurl);
HttpURLConnection coon= (HttpURLConnection) url.openConnection();
coon.setRequestMethod("POST");
String text="name="+name+"&pass="+pass;
OutputStream outputStream=coon.getOutputStream();
outputStream.write(text.getBytes());
BufferedReader bf=new BufferedReader(new InputStreamReader(coon.getInputStream()));
String str;
StringBuffer sb=new StringBuffer();
while((str=bf.readLine())!=null){
sb.append(str);
}
Log.i("test",sb.toString());
HTTPClient get方式:
httpurl=httpurl+"?name="+name+"&pass="+pass;
HttpClient httpClient=new DefaultHttpClient();
HttpGet httpGet=new HttpGet(httpurl);
try {
httpClient.execute(httpGet);
} catch (IOException e) {
e.printStackTrace();
}
HTTPclient post方式:
private void doclientpost() {
HttpClient client=new DefaultHttpClient();
HttpPost post=new HttpPost(httpurl);
try {
List<NameValuePair> pairs=new ArrayList<NameValuePair>();
pairs.add(new BasicNameValuePair("name",name));
pairs.add(new BasicNameValuePair("pass",pass));
UrlEncodedFormEntity entity=new UrlEncodedFormEntity(pairs,"utf-8");
post.setEntity(entity);
HttpResponse response=client.execute(post);
if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){
HttpEntity entity1=response.getEntity();
String s= EntityUtils.toString(entity1,"utf-8");
Log.i("test",s);
}
} catch (IOException e) {
e.printStackTrace();
}
}
同时,为了更好地与网络进行交互,总要解析XML和JSON 下面以HttpUrlConnecttion进行例子:
private void urlconnectGetXml() {
URL url;
try {
url=new URL(httpurl);
HttpURLConnection coon= (HttpURLConnection) url.openConnection();//建立连接
InputStream in=coon.getInputStream();//获得输入流
XmlPullParserFactory factory=XmlPullParserFactory.newInstance();//获得工厂类
XmlPullParser parser=factory.newPullParser();//通过工厂类获得解析类
int event=parser.getEventType();//获得解析类的状态码
parser.setInput(in,"utf-8");//解析输入流
String id="";
String name="";
String age="";
//循环遍历所有的xml节点对象
while(event!=XmlPullParser.END_DOCUMENT){
String nodename=parser.getName();//获得节点的名字
switch (event){
//XmlPullParser.START_TAG标识意味着解析开始
case XmlPullParser.START_TAG :{
if ("id".equals(nodename)) {
id = parser.nextText();
}
if ("name".equals(nodename)) {
name = parser.nextText();
}
if ("age".equals(nodename)) {
age = parser.nextText();
}
break;
}
//XmlPullParser.END_TAG意味着解析结束
case XmlPullParser.END_TAG:{
if("student".equals(nodename)){
Log.i("test",id+" "+name+" "+age+"\n");
}
break;
}
}
//手动的让XML解析下一个节点
event=parser.next();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}
JSON格式:
public List<NewsBean> getdata(String url){
String JsonUrl=null;
NewsBean bean;
try {
JsonUrl=readurl(new URL(url).openStream());//通过传入一个流 调用readurl方法 得到json数据
JSONObject jsonObject=new JSONObject(JsonUrl);
JSONArray array=jsonObject.getJSONArray("data");
/**
* 通过遍历json数组,得到所有的json对象,然后通过getstring的方式得到json对象中的的URL,并将其赋值为
* 集合中bean对象的string
*/
for (int i = 0; i <array.length() ; i++) {
jsonObject=array.getJSONObject(i);
bean=new NewsBean();
bean.Title=jsonObject.getString("name");
bean.Content=jsonObject.getString("description");
bean.IconUrl=jsonObject.getString("picSmall");
bean.BigImage=jsonObject.getString("picBig");
mList.add(bean);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
Log.i("test",JsonUrl);
return mList;
}
同时还有一个模仿迅雷的多线程下载技术:
1 首先我们创建一个handler来准备进行UI更新
2在创建一个线程 线程中创建一个线程池用来管理和启动随后的多线程下载
3写一个继承与Runable接口的类A,这个类用来进行下载
4 在线程中获得所下载文件的大小,并且根据线程数来分割成N块,通过调用FOR循环来创建A。这里需要注意的是,当分割为N的时候,当循环计数到了N的时候
end应该直接为文件最后的大小。例如 11分为3份 0-2 3-5 6-10 不然的话 6-9就会出现数据丢失现象
5 在A中的方法如下
//这个就是线程池,用来管理
private Executor executor= Executors.newFixedThreadPool(3);
static class DownRunnable implements Runnable{
private String url1;
private String fileName;
private Handler handler2;
private long start;//定义开始下载的字节数
private long end;//定义结束下载的字节数
public DownRunnable(String url,String fileName,Handler handler2,long start,long end) {
this.start = start;
this.handler2 = handler2;
this.fileName = fileName;
this.url1 = url;
this.end = end;
}
@Override
public void run() {
Log.i("test","进入到图片下载线程中");
try {
URL url=new URL(url1);
HttpURLConnection coon= (HttpURLConnection) url.openConnection();
coon.setRequestMethod("GET");
coon.setReadTimeout(5000);
//这里第一个参数为Range为范围,第二个指定bytes的开始和结束位置
coon.setRequestProperty("Range","bytes="+start+"-"+end);
Log.i("test",fileName);
//用文件读写来创建一个可读可写可执行的文件,并且通过随机读取的方式读入下载的字节数
RandomAccessFile file=new RandomAccessFile(new File(fileName),"rwd");
file.seek(start);
InputStream in=coon.getInputStream();
byte [] b=new byte[1024*4];
int len=0;
Log.i("test","线程下载文件信息:开始="+start+",结束="+end);
while((len=in.read(b))!=-1){
//通过调用sendmessage方法异步更新UI
Message message=handler2.obtainMessage();
message.arg1=len;
handler2.sendMessage(message);
file.write(b,0,len);
Log.i("tes","下载图片进度:"+len);
}
if(file!=null){
file.close();
}
if(in!=null){
in.close();
}
Message message=handler2.obtainMessage();
message.what=1;
handler2.sendMessage(message);
Log.i("test","已经发送msg.what");
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
至此博客写完 滚去睡觉了、