Android开发请求网络方式详解

转载请注明出处:http://blog.csdn.net/allen315410/article/details/42643401

大家知道Google支持和发布的Android移动操作系统,主要是为了使其迅速占领移动互联网的市场份额,所谓移动互联网当然也是互联网了,凡是涉及互联网的任何软件任何程序都少不了联网模块的开发,诚然Android联网开发也是我们开发中至关重要的一部分,那么Android是怎么样进行联网操作的呢?这篇博客就简单的介绍一下Android常用的联网方式,包括JDK支持的HttpUrlConnection,Apache支持的HttpClient,以及开源的一些联网框架(譬如AsyncHttpClient)的介绍。本篇博客只讲实现过程和方式,不讲解原理,否则原理用文字很难以讲清,其实我们知道怎么去用,就可以解决一些基本开发需要了。

绝大多数的Android应用联网都是基于Http协议的,也有很少是基于Socket的,我们这里主要讲解基于Http协议的联网方式。讲解实例是建立在一个模拟的登录小模块中进行,登录请求数据仅仅只有username和password两个简单字段。

HttpUrlConnection

HttpUrlConnection是JDK里提供的联网API,我们知道Android SDK是基于Java的,所以当然优先考虑HttpUrlConnection这种最原始最基本的API,其实大多数开源的联网框架基本上也是基于JDK的HttpUrlConnection进行的封装罢了,掌握HttpUrlConnection需要以下几个步骤:

1将访问的路径转换成URL。

URL url = new URL(path);

2,通过URL获取连接。

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

3,设置请求方式。

conn.setRequestMethod("GET");

4,设置连接超时时间。

conn.setConnectTimeout(5000);

5,设置请求头的信息。

conn.setRequestProperty("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)");

6,获取响应码

int code = conn.getResponseCode();

7,针对不同的响应码,做不同的操作

7.1,请求码200,表明请求成功,获取返回内容的输入流

InputStream is = conn.getInputStream();

7.2,将输入流转换成字符串信息

public class StreamTools {
	/**
	 * 将输入流转换成字符串
	 *
	 * @param is
	 *            从网络获取的输入流
	 * @return
	 */
	public static String streamToString(InputStream is) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = is.read(buffer)) != -1) {
				baos.write(buffer, 0, len);
			}
			baos.close();
			is.close();
			byte[] byteArray = baos.toByteArray();
			return new String(byteArray);
		} catch (Exception e) {
			Log.e("tag", e.toString());
			return null;
		}
	}
}

7.3,若返回值400,则是返回网络异常,做出响应的处理。

HttpUrlConnection发送GET请求

/**
	 * 通过HttpUrlConnection发送GET请求
	 *
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByGet(String username, String password) {
		String path = "http://192.168.0.107:8080/WebTest/LoginServerlet?username=" + username + "&password=" + password;
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("GET");
			int code = conn.getResponseCode();
			if (code == 200) {
				InputStream is = conn.getInputStream(); // 字节流转换成字符串
				return StreamTools.streamToString(is);
			} else {
				return "网络访问失败";
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "网络访问失败";
		}
	}

HttpUrlConnection发送POST请求

/**
	 * 通过HttpUrlConnection发送POST请求
	 *
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByPost(String username, String password) {
		String path = "http://192.168.0.107:8080/WebTest/LoginServerlet";
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setConnectTimeout(5000);
			conn.setRequestMethod("POST");
			conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
			String data = "username=" + username + "&password=" + password;
			conn.setRequestProperty("Content-Length", data.length() + "");
			// POST方式,其实就是浏览器把数据写给服务器
			conn.setDoOutput(true); // 设置可输出流
			OutputStream os = conn.getOutputStream(); // 获取输出流
			os.write(data.getBytes()); // 将数据写给服务器
			int code = conn.getResponseCode();
			if (code == 200) {
				InputStream is = conn.getInputStream();
				return StreamTools.streamToString(is);
			} else {
				return "网络访问失败";
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "网络访问失败";
		}
	}

HttpClient

HttpClient是开源组织Apache提供的Java请求网络框架,其最早是为了方便Java服务器开发而诞生的,是对JDK中的HttpUrlConnection各API进行了封装和简化,提高了性能并且降低了调用API的繁琐,Android因此也引进了这个联网框架,我们再不需要导入任何jar或者类库就可以直接使用,值得注意的是Android官方已经宣布不建议使用HttpClient了,我们再开发的时候尽量少用吧,但是用了也无妨!

HttpClient发送GET请求

1, 创建HttpClient对象

2,创建HttpGet对象,指定请求地址(带参数)

3,使用HttpClient的execute(),方法执行HttpGet请求,得到HttpResponse对象

4,调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

5,调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

/**
	 * 通过HttpClient发送GET请求
	 *
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByHttpClientGet(String username, String password) {
		String path = "http://192.168.0.107:8080/WebTest/LoginServerlet?username="
				+ username + "&password=" + password;
		HttpClient client = new DefaultHttpClient(); // 开启网络访问客户端
		HttpGet httpGet = new HttpGet(path); // 包装一个GET请求
		try {
			HttpResponse response = client.execute(httpGet); // 客户端执行请求
			int code = response.getStatusLine().getStatusCode(); // 获取响应码
			if (code == 200) {
				InputStream is = response.getEntity().getContent(); // 获取实体内容
				String result = StreamTools.streamToString(is); // 字节流转字符串
				return result;
			} else {
				return "网络访问失败";
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "网络访问失败";
		}
	}

HttpClient发送POST请求

1,创建HttpClient对象

2,创建HttpPost对象,指定请求地址

3,创建List<NameValuePair>,用来装载参数

4,调用HttpPost对象的setEntity()方法,装入一个UrlEncodedFormEntity对象,携带之前封装好的参数

5,使用HttpClient的execute()方法执行HttpPost请求,得到HttpResponse对象

6, 调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

7, 调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

/**
	 * 通过HttpClient发送POST请求
	 *
	 * @param username
	 * @param password
	 * @return
	 */
	public static String loginByHttpClientPOST(String username, String password) {
		String path = "http://192.168.0.107:8080/WebTest/LoginServerlet";
		try {
			HttpClient client = new DefaultHttpClient(); // 建立一个客户端
			HttpPost httpPost = new HttpPost(path); // 包装POST请求
			// 设置发送的实体参数
			List<NameValuePair> parameters = new ArrayList<NameValuePair>();
			parameters.add(new BasicNameValuePair("username", username));
			parameters.add(new BasicNameValuePair("password", password));
			httpPost.setEntity(new UrlEncodedFormEntity(parameters, "UTF-8"));
			HttpResponse response = client.execute(httpPost); // 执行POST请求
			int code = response.getStatusLine().getStatusCode();
			if (code == 200) {
				InputStream is = response.getEntity().getContent();
				String result = StreamTools.streamToString(is);
				return result;
			} else {
				return "网络访问失败";
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "访问网络失败";
		}
	}

其他开源联网框架

AsyncHttpClient

除了上述Android官方推荐的联网框架以外,在开源世界里关于联网框架真是太多太多了,例如afinal,xutils等等,都是一些开源大牛自己封装的联网框架,并且在GitHub开源社区中可以下载到,其实类似的开源联网框架基本上也是基于HttpUrlConnection的进一步封装,大大提高了性能,同时更加简化了使用方法,这里使用AsyncHttpClient作为案例,其他的联网框架大家可以去网上找,下载使用试试便可。

AsyncHttpClient是一个非常优秀的联网框架,不仅支持所有Http请求的方式,而且还支持文件的上传和下载,要知道用HttpUrlConnection写一个文件上传和下载健全功能是很需要花费一定时间和精力的,因为请求头实在是太多了,稍有不慎就会写错。但是AsyncHttpClient已经封装好了这些“麻烦”,我们只需要下载到AsyncHttpClient的jar包或者源码导入项目中,Http,上传,下载等等,只需要几个简单的api即可搞定。

AsyncHttpClient的GitHub主页:https://github.com/AsyncHttpClient/async-http-client/

AsyncHttpClient发送GET请求

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,调用该类的get方法发送GET请求,传入请求资源地址URL,创建AsyncHttpResponseHandler对象

4,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

/**
	 * 通过AsyncHttpClient发送GET请求
	 */
	public void loginByAsyncHttpGet() {
		String path = "http://192.168.0.107:8080/WebTest/LoginServerlet?username=zhangsan&password=123";
		AsyncHttpClient client = new AsyncHttpClient();
		client.get(path, new AsyncHttpResponseHandler() {

			@Override
			public void onFailure(int arg0, Header[] arg1, byte[] arg2,
					Throwable arg3) {
				// TODO Auto-generated method stub
				Log.i("TAG", "请求失败:" + new String(arg2));
			}

			@Override
			public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
				// TODO Auto-generated method stub
				Log.i("TAG", "请求成功:" + new String(arg2));
			}
		});
	}

AsyncHttpClient发送POST请求

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,创建请求参数,RequestParams对象

4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象

5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

/**
	 * 通过AsyncHttpClient发送POST请求
	 */
	public void loginByAsyncHttpPost() {
		String path = "http://192.168.0.107:8080/WebTest/LoginServerlet";
		AsyncHttpClient client = new AsyncHttpClient();
		RequestParams params = new RequestParams();
		params.put("username", "zhangsan");
		params.put("password", "123");
		client.post(path, params, new AsyncHttpResponseHandler() {

			@Override
			public void onFailure(int arg0, Header[] arg1, byte[] arg2,
					Throwable arg3) {
				// TODO Auto-generated method stub
				Log.i("TAG", "请求失败:" + new String(arg2));
			}

			@Override
			public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {
				// TODO Auto-generated method stub
				Log.i("TAG", "请求成功:" + new String(arg2));
			}
		});
	}

AsyncHttpClient上传文件

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,创建请求参数,RequestParams对象,请求参数仅仅包含文件对象即可,例如:

params.put("profile_picture", new File("/sdcard/pictures/pic.jpg"));

4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象

5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

判断网络连接状态

很多时候对于手机或者平板电脑这样的手持设备,我们是不知道它们的网络连接状态的,在联网的时候我们必须得保证设备的网路是否正常,是否可以连接上互联网,或者我们在进行大量数据上传或者下载,例如下载网路视频,看网路电视等等,我们必须得为用户省钱,这样大数据的传输显然是不能使用用户昂贵的数据流量的,而是判断当前网络是不是在wifi下,使用WiFi来进行大数据的传输,会给用户更好的体验,那么下面这个工具类就是用来判断设备网络连接状态的,不仅判断了当前设置手机网络下还是WiFi环境下,而且如果手机网络下还需要设置运营商的代理IP和端口。

/**
 * 判断网络状态的工具类
 *
 */
public class NetworkUtil {

	/* 代码IP */
	private static String PROXY_IP = null;
	/* 代理端口 */
	private static int PROXY_PORT = 0;
	/**
	 * 判断当前是否有网络连接
	 *
	 * @param context
	 * @return
	 */
	public static boolean isNetwork(Context context) {
		boolean network = isWifi(context);
		boolean mobilework = isMobile(context);
		if (!network && !mobilework) { // 无网络连接
			Log.i("NetworkUtil", "无网路链接!");
			return false;
		} else if (network == true && mobilework == false) { // wifi连接
			Log.i("NetworkUtil", "wifi连接!");
		} else { // 网络连接
			Log.i("NetworkUtil", "手机网路连接,读取代理信息!");
			readProxy(context); // 读取代理信息
			return true;
		}
		return true;
	}

	/**
	 * 读取网络代理
	 *
	 * @param context
	 */
	private static void readProxy(Context context) {
		Uri uri = Uri.parse("content://telephony/carriers/preferapn");
		ContentResolver resolver = context.getContentResolver();
		Cursor cursor = resolver.query(uri, null, null, null, null);
		if (cursor != null && cursor.moveToFirst()) {
			PROXY_IP = cursor.getString(cursor.getColumnIndex("proxy"));
			PROXY_PORT = cursor.getInt(cursor.getColumnIndex("port"));
		}
		cursor.close();
	}

	/**
	 * 判断当前网络是否是wifi局域网
	 *
	 * @param context
	 * @return
	 */
	public static boolean isWifi(Context context) {
		ConnectivityManager manager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = manager
				.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		if (info != null) {
			return info.isConnected(); // 返回网络连接状态
		}
		return false;
	}

	/**
	 * 判断当前网络是否是手机网络
	 *
	 * @param context
	 * @return
	 */
	public static boolean isMobile(Context context) {
		ConnectivityManager manager = (ConnectivityManager) context
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo info = manager
				.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		if (info != null) {
			return info.isConnected(); // 返回网络连接状态
		}
		return false;
	}
}
时间: 2024-10-06 10:00:00

Android开发请求网络方式详解的相关文章

Android开发四大组件--Activity详解

Android开发四大组件--Activity详解 - Android开发教程 Android开发的四大组件在开发中应用中是必不可少的,下面就来详解下四大组件之一Activity,总结自网络.Activty的生命周期的也就是它所在进程的生命周期. 一个Activity的启动顺序: onCreate()——>onStart()——>onResume() 当另一个Activity启动时: 第一个Activity onPause()——>第二个Activity onCreate()——>

Android开发之通知栏Notification详解

Notification的用法  --- 状态栏通知 发送一个状态栏通知必须的两个类: 1. NotificationManager   --- 状态栏通知的管理类,负责发通知,清除通知等 NotificationManager : 是一个系统Service,必须通过 context.getSystemService(NOTIFICATION_SERVICE)方法获取 NotificationManager notificationManager = (NotificationManager)

虚拟机的几种网络方式详解

虚拟机的几种网络方式详解本部分作为2部分进行讲解1.虚拟机常见的上网模式详细解析2.在使用虚拟机中常见的问题处理 先看问题1虚拟机常见的上网模式详细解析虚拟机就是利用真实机的环境用软件的方式模拟成类似真实机系统的一个软件,现在主流的有微软的虚拟机,有vmare,orcale virtualBOx(orcale  virtualBOx原名叫做Sun virtualBOx 前不久刚被orcale公司收购所以改名为orcale  virtualBOx)那么不管是那种虚拟机,在虚拟机软件都内置了几种虚拟

Android开发:程序目录结构详解

HelloWorld程序的目录结构概述 我们可以在文件夹中看到,HelloWorld程序的目录主要包括:src文件夹.gen文件夹.Android文件夹.assets.res文件夹. AndroidManifest.xml.default.properties.在Eclipse的左侧展开HelloWorld项目,可以看到如下图的目录结构: 下面将分节介绍上面的各级目录结构. 1.src文件夹 顾名思义(src, source code)该文件夹是放项目的源代码的.打开HelloWorld.jav

android开发中SharedPreferences用法详解(含源代码和运行结果截图)

在Android应用程序开发中,经常需要保存一些类似于配置信息的简单类型数据,比如游戏玩家的积分.是否开启音效等.SharedPreferences类为我们保存.读取这些数据提供了便利. SharedPreferences接口提供以下常用方法来访问SharedPreferences对象中的key-value对: boolean contains(String key):判断SharedPreferences对象是否包含键值为key的数据. boolean getXxx(String key, x

Android开发 Activity生命周期详解

前言 在一般情况下了解Activity的生命周期后,都很容易认为自己已经理解了生命周期.并且可能会觉得实际运用起来并不需要这么多的生命周期来处理activity.但是Activity的生命周期的设计理念远远不止是让你知道Activity是在创建还是前台还是在后台或者销毁这般简单.特别是在初始化与释放资源的这难点上,只有深入理解了Activity的生命周期才会让你不会出现各种资源提早释放导致空指针,资源释放失败导致内存泄露,反复初始化导致性能开销大的问题. 生命周期流程图 原文地址:https:/

Docker基础 :网络配置详解

本篇文章将讲述 Docker 的网络功能,包括使用端口映射机制来将容器内应用服务提供给外部网络,以及通过容器互联系统让多个容器之间进行快捷的网络通信,有兴趣的可以了解下. 大量的互联网应用服务包含多个服务组件,这往往需要多个容器之间通过网络通信进行相互配合.Docker 目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网络服务.接下来我们将讲述 Docker 的网络功能,包括使用端口映射机制来将容器内应用服务提供给外部网络,以及通过容器互联系统让多个容器之间进行快捷的网络通信. 端口映

Android中的几种网络请求方式详解

http://blog.csdn.net/zuolongsnail/article/details/6373051 Android应用中使用AsyncHttpClient来异步网络数据 http://blog.csdn.net/sdvch/article/details/13615605 Android中的几种网络请求方式详解,布布扣,bubuko.com

Android开发之网络请求通信专题(二):基于HttpClient的文件上传下载

上一篇专题Android开发之网络请求通信专题(一):基于HttpURLConnection的请求通信我们讲解了如何使用httpurlconnection来实现基本的文本数据传输.一般在实际开发中我们可以用于传输xml或者json格式的数据.今天我们来讲解另外一种http网络请求的方式:httpclient,并实现文件的上传和下载. 在这里插个题外话,其实这些网络请求有很多第三方jar包可以使用,这些包都封装得很好了.如果只是想使用,我们就直接拿别人得jar包来用就好.博主这里推荐一个叫xuti