大家知道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,用来装载参数

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 parameters = new ArrayList();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() {@Overridepublic void onFailure(int arg0, Header[] arg1, byte[] arg2,Throwable arg3) {// TODO Auto-generated method stubLog.i(TAG, 请求失败: + new String(arg2));}@Overridepublic void onSuccess(int arg0, Header[] arg1, byte[] arg2) {// TODO Auto-generated method stubLog.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() {@Overridepublic void onFailure(int arg0, Header[] arg1, byte[] arg2,Throwable arg3) {// TODO Auto-generated method stubLog.i(TAG, 请求失败: + new String(arg2));}@Overridepublic void onSuccess(int arg0, Header[] arg1, byte[] arg2) {// TODO Auto-generated method stubLog.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;}}

更多相关文章

  1. 类和 Json对象
  2. Android使用Retrofit进行网络请求
  3. Android中文API(144) —— JsonWriter
  4. Android之Handler用法总结
  5. android通过ksoap2对webservice的解析
  6. Android中判断网络功能是否可用
  7. Android的网络状态判断
  8. Android(安卓)Paging组件Demo
  9. Android(安卓)View的介绍和使用

随机推荐

  1. ubuntu 陪在android sdk 地址映射
  2. Android 通过GPS进行定位
  3. android dexposed框架hook使用实例
  4. Android Market 多APK 包支持
  5. Android 的反编译
  6. 深入了解Handler的消息传递机制
  7. Android 图片拖动 放大
  8. 【Android源码】Android(安卓)UI 之一步
  9. 杞細 The System Server in Android
  10. Android 调用联系人列表,选择联系人