Android:Http通信协议

    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方法安全的。由于自己不懂搭建服务器,所以这个有点不好测试,先留个印象吧!


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。