大家知道Google支持和发布的Android移动操作系统,主要是为了使其迅速占领移动互联网的市场份额,所谓移动互联网当然也是互联网了,凡是涉及互联网的任何软件任何程序都少不了联网模块的开发,诚然Android联网开发也是我们开发中至关重要的一部分,那么Android是怎么样进行联网操作的呢?这篇博客就简单的介绍一下Android常用的联网方式,包括JDK支持的HttpUrlConnection,Apache支持的HttpClient,以及开源的一些联网框架(譬如AsyncHttpClient)的介绍。本篇博客只讲实现过程和方式,不讲解原理,否则原理用文字很难以讲清,其实我们知道怎么去用,就可以解决一些基本开发需要了。
绝大多数的Android应用联网都是基于Http协议的,也有很少是基于Socket的,我们这里主要讲解基于Http协议的联网方式。讲解实例是建立在一个模拟的登录小模块中进行,登录请求数据仅仅只有username和password两个简单字段。
HttpUrlConnection
1将访问的路径转换成URL。
URL url = new URL(path);
2,通过URL获取连接。
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
3,设置请求方式。
conn.setRequestMethod("GET");
conn.setRequestMethod("GET");
4,设置连接超时时间。
conn.setConnectTimeout(5000);
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;
- }
- }
- }
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发送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 "网络访问失败";
- }
- }
/**
* 通过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发送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发送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 "访问网络失败";
- }
- }
/**
* 通过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
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发送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发送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"));
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;
- }
- }