Android-HttpClient连接网络获取数据
2015-11-14 22:32
549 查看
大部分Android App都使用HttpURLConnection 和 Apache
HTTP Client来发送和接收网络数据(不包括第三方开源项目),这两者都支持HTTPS,流上传和下载,可配置超时,IPv6和连接池。
1)关于Apache HTTP Client:
DefaultHttpClient(android5.1\external\apache-http\src\org\apache\http\impl\client\DefaultHttpClient.java)和
AndroidHttpClient(android5.1\frameworks\base\core\java\android\net\http\AndroidHttpClient.java)都继承于HttpClient。它们有庞大且灵活的API,还比较稳定,尽管有少量的bug。然而在不破坏它们兼容性的前提下,它们庞大的API却阻碍了它们得到进一步的改进和提升。为此,Android
团队慢慢开始放弃Apache HTTP Client,在Android 6.0中,已经移除了Apache HTTP Client,在Android 官方文档中可查:http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client。
2)关于HttpURLConnection:
HttpURLConnection的是一个通用的,适用于大多数应用的轻量级HTTP客户端。这个类出现的时候比较低调,因为其早期版本会有一些bug,但其专注的API使得它们很容易被稳步改善。在升级到Android2.2之前,HttpURLConnection有些令人沮丧的错误,特别是,在一个可读的InputStream中调用close(),可能会毒害这个链接池。为此需要禁用连接池:
(1)使用Url.openConnection()来获得一个新的HttpURLConnection。
(2)准备request:request主要属性是它的url。request header可以包括metadata,比如凭证(credentials),首选内容类型和session cookies。
(3)选择性的上传request的主体,如果它们包括一个request body,实例对象必须设置setDoOutput(true)。被写入到stream的传输数据通过getOutputStream返回。
(4)读取response,response header通常包括metadata,如response主体内容类型和长度、修改日期和session cookies。response主体可能从通过getInputStream返回的stream中读取的。如果response没有主体,该方法返回一个空的stream。
(5)断开:一旦response主体被读取到,HttpURLConnection应该调用disconnect()来断开,释放连接所持有的资源。
1)首先在Manifest文件中增加访问网络的权限:
2)检测手机联网的状态,手机可能没有联网,连接了网络,还要区分是移动数据还是WIFI。同时在网络连接发生变化时,需要接受系统的广播:
android.net.conn.CONNECTIVITY_CHANGE,所以需要注册广播。这里简单的用一个类来管理网络连接的状态:
3)异步执行网络操作:因为在主线程执行网络操作,如果网络操作执行的时间稍长,就可能导致UI主线程线程ANR,这里以Async Task来异步执行网络操作:
参考:http://developer.android.com/training/basics/network-ops/connecting.html
http://developer.android.com/reference/java/net/HttpURLConnection.html http://developer.android.com/training/basics/network-ops/managing.html
HTTP Client来发送和接收网络数据(不包括第三方开源项目),这两者都支持HTTPS,流上传和下载,可配置超时,IPv6和连接池。
1)关于Apache HTTP Client:
DefaultHttpClient(android5.1\external\apache-http\src\org\apache\http\impl\client\DefaultHttpClient.java)和
AndroidHttpClient(android5.1\frameworks\base\core\java\android\net\http\AndroidHttpClient.java)都继承于HttpClient。它们有庞大且灵活的API,还比较稳定,尽管有少量的bug。然而在不破坏它们兼容性的前提下,它们庞大的API却阻碍了它们得到进一步的改进和提升。为此,Android
团队慢慢开始放弃Apache HTTP Client,在Android 6.0中,已经移除了Apache HTTP Client,在Android 官方文档中可查:http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-apache-http-client。
2)关于HttpURLConnection:
HttpURLConnection的是一个通用的,适用于大多数应用的轻量级HTTP客户端。这个类出现的时候比较低调,因为其早期版本会有一些bug,但其专注的API使得它们很容易被稳步改善。在升级到Android2.2之前,HttpURLConnection有些令人沮丧的错误,特别是,在一个可读的InputStream中调用close(),可能会毒害这个链接池。为此需要禁用连接池:
privatevoid disableConnectionReuseIfNecessary(){ // HTTP connection reuse which was buggy pre-froyo if(Integer.parseInt(Build.VERSION.SDK)<Build.VERSION_CODES.FROYO){ System.setProperty("http.keepAlive","false"); } }
使用HttpURLConnection类::
(1)使用Url.openConnection()来获得一个新的HttpURLConnection。
(2)准备request:request主要属性是它的url。request header可以包括metadata,比如凭证(credentials),首选内容类型和session cookies。
(3)选择性的上传request的主体,如果它们包括一个request body,实例对象必须设置setDoOutput(true)。被写入到stream的传输数据通过getOutputStream返回。
(4)读取response,response header通常包括metadata,如response主体内容类型和长度、修改日期和session cookies。response主体可能从通过getInputStream返回的stream中读取的。如果response没有主体,该方法返回一个空的stream。
(5)断开:一旦response主体被读取到,HttpURLConnection应该调用disconnect()来断开,释放连接所持有的资源。
综合上述,以HttpURLConnection为例来实现简单连接网络获取数据:
1)首先在Manifest文件中增加访问网络的权限:
<uses-permissionandroid:name="android.permission.INTERNET"/> <uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE"/>
2)检测手机联网的状态,手机可能没有联网,连接了网络,还要区分是移动数据还是WIFI。同时在网络连接发生变化时,需要接受系统的广播:
android.net.conn.CONNECTIVITY_CHANGE,所以需要注册广播。这里简单的用一个类来管理网络连接的状态:
public class NetConnectMananger { private Context mContext; private ConnectivityManager cm; private NetworkInfo networkInfo; private NetWorkChangedReceiver mNetWorkChangedReceiver; //判断是否是WIFI连接网络 private static boolean isWifiConnected = false; //判断是否是移动数据连接网络 private static boolean isMobileConnected = false; public NetConnectMananger(Context context){ mContext = context; cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); setMobileType(); //动态注册广播 mNetWorkChangedReceiver = new NetWorkChangedReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); context.registerReceiver(mNetWorkChangedReceiver, intentFilter); } public boolean isWifiNetWork(){ return isWifiConnected; } public boolean isMobileNetWork(){ return isMobileConnected; } /** * 根据当前网络的状态来设置网络连接的TYPE * */ private void setMobileType(){ networkInfo = cm.getActiveNetworkInfo(); if(networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE){ isMobileConnected = true; }else if(networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI){ isWifiConnected = true; }else{ isWifiConnected = false; isMobileConnected = false; } } /** * 取消广播的注册 * */ public void unRegisterNetWorkChangedReceiver(){ mContext.unregisterReceiver(mNetWorkChangedReceiver); } /** * 接收网络连接发生改变的广播:android.net.conn.CONNECTIVITY_CHANGE * */ public class NetWorkChangedReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { setMobileType(); } }<span style="font-family: 微软雅黑; widows: auto; background-color: inherit;"> </span><span style="font-family: 微软雅黑; widows: auto; background-color: inherit;"> </span>
3)异步执行网络操作:因为在主线程执行网络操作,如果网络操作执行的时间稍长,就可能导致UI主线程线程ANR,这里以Async Task来异步执行网络操作:
... private static final String url = http://www.weather.com.cn/data/sk/101010100.html; private NetConnectMananger ncm; ... @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_start_http: if(ncm.isMobileNetWork() || ncm.isWifiNetWork()){ new DownLoadTask().execute(url); }else{ Toast.makeText(getApplicationContext(), "请确认网络是否连接!", Toast.LENGTH_LONG).show(); } break; default: break; } } @Override protected void onDestroy() { super.onDestroy(); //取消ncm中注册的广播。 ncm.unRegisterNetWorkChangedReceiver(); } private class DownLoadTask extends AsyncTask<String, Void, String>{ @Override protected String doInBackground(String... url) { if(url != null){ try { return downLoadData(url[0]); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } @Override protected void onPostExecute(String result) { mTextView.setText(result); } public String downLoadData(String url) throws IOException{ InputStream stream = null; int len = 500; if(url == null){ Toast.makeText(getApplicationContext(), "无效网址!", Toast.LENGTH_LONG).show(); return null; } URL mUrl = new URL(url); HttpURLConnection urlConnection = (HttpURLConnection) mUrl.openConnection(); try{ urlConnection.setReadTimeout(1000); urlConnection.setConnectTimeout(20000); urlConnection.setRequestMethod("GET"); urlConnection.setDoInput(true); urlConnection.connect(); int response = urlConnection.getResponseCode(); Log.i(TAG, "The response is: " + response); stream = urlConnection.getInputStream(); String dataString = getStringFromStream(stream, len); return dataString; }finally{ if(stream != null){ stream.close(); } if(urlConnection != null){ urlConnection.disconnect(); } } } public String getStringFromStream(InputStream in, int len) throws UnsupportedEncodingException, IOException{ Reader reader = null; reader = new InputStreamReader(in, "UTF-8"); char[] buffer = new char[len]; reader.read(buffer); return new String(buffer); } }
参考:http://developer.android.com/training/basics/network-ops/connecting.html
http://developer.android.com/reference/java/net/HttpURLConnection.html http://developer.android.com/training/basics/network-ops/managing.html
相关文章推荐
- Android 通过开源框架实现加载网络图片并下载到SD卡通知系统相册显示,(并实现分享图片功能)
- TCP/IP数据包处理路径(Ipnat.sys 、Ipfltdrv.sys 、 Ipsec.sys)
- 建立TCP连接的三次握手
- 确认字符ACK
- SYN及SYN攻击
- Android网络优化4--写一个网络请求模板
- python复杂网络库networkx:基础
- python复杂网络库networkx:基础
- django的HTTPREQUEST对象
- 无线网络方案
- 【TCP/IP协议】四层协议系统
- 网络采集器Demo:Jsoup+Java多线程实现[爬虫](下)
- HttpClient在Android网络通信中的应用
- 10010---JavaWeb基础--HttpServlet
- MOOC课程作业http://mooc.study.163.com/course/USTC-1000002006
- iOS9的网络请求简述
- “App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. T
- Android网络优化3--基本方法
- Tinyhttpd源码剖析(二)
- 简单的网络编程--服务器,客户端呼应