Android网络:HTTP之利用HttpURLConnection访问网页、获取网络图片实例 (附源码)

http://blog.csdn.net/yanzi1225627/article/details/22222735

前文所示的TCP局域网传送东西,除了对传输层的TCP/UDP支持良好外,Android对HTTP(超文本传输协议)也提供了很好的支持,这里包括两种接口:

1、标准Java接口(java.net) ----HttpURLConnection,可以实现简单的基于URL请求、响应功能;

2、Apache接口(org.appache.http)----HttpClient,使用起来更方面更强大。一般来说,用这种接口。不过本文还是把第一种接口过一下。

任何一种接口,无外乎四个基本功能:访问网页、下载图片或文件、上传文件.本文示范的是访问网页和下载图片。HttpURLConnection继承自URLConnection类,用它可以发送和接口任何类型和长度的数据,且预先不用知道数据流的长度,可以设置请求方式get或post、超时时间。

下面直接贴代码,代码目的有两个,一是访问百度首页,获取其返回的html字符串,二是给定URL下载个图片并显示出来。后续将展开系列博文介绍HTTP相关知识。

activity_main.xml

[html] view plaincopyprint?

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:id="@+id/parent_view"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:paddingBottom="@dimen/activity_vertical_margin"
  7. android:paddingLeft="@dimen/activity_horizontal_margin"
  8. android:paddingRight="@dimen/activity_horizontal_margin"
  9. android:paddingTop="@dimen/activity_vertical_margin"
  10. tools:context=".MainActivity" >
  11. <FrameLayout
  12. android:layout_width="match_parent"
  13. android:layout_height="match_parent" >
  14. <TextView
  15. android:id="@+id/textview_show"
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:text="@string/hello_world" />
  19. <ImageView
  20. android:id="@+id/imagview_show"
  21. android:layout_width="wrap_content"
  22. android:layout_height="wrap_content"
  23. android:layout_gravity="center" />
  24. </FrameLayout>
  25. <Button
  26. android:id="@+id/btn_visit_web"
  27. android:layout_width="wrap_content"
  28. android:layout_height="wrap_content"
  29. android:layout_alignParentBottom="true"
  30. android:layout_alignParentLeft="true"
  31. android:text="访问百度" />
  32. <Button
  33. android:id="@+id/btn_download_img"
  34. android:layout_width="wrap_content"
  35. android:layout_height="wrap_content"
  36. android:layout_alignParentBottom="true"
  37. android:layout_toRightOf="@id/btn_visit_web"
  38. android:text="下载图片"/>
  39. </RelativeLayout>

MainActivity.java

[java] view plaincopyprint?

  1. package org.yanzi.httpurlconnection;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.net.HttpURLConnection;
  7. import java.net.MalformedURLException;
  8. import java.net.URL;
  9. import android.app.Activity;
  10. import android.content.Context;
  11. import android.graphics.Bitmap;
  12. import android.graphics.BitmapFactory;
  13. import android.os.AsyncTask;
  14. import android.os.Bundle;
  15. import android.view.Menu;
  16. import android.view.View;
  17. import android.view.ViewGroup;
  18. import android.widget.Button;
  19. import android.widget.ImageView;
  20. import android.widget.ProgressBar;
  21. import android.widget.RelativeLayout;
  22. import android.widget.TextView;
  23. public class MainActivity extends Activity {
  24. Button visitWebBtn = null;
  25. Button downImgBtn = null;
  26. TextView showTextView = null;
  27. ImageView showImageView = null;
  28. String resultStr = "";
  29. ProgressBar progressBar = null;
  30. ViewGroup viewGroup = null;
  31. @Override
  32. protected void onCreate(Bundle savedInstanceState) {
  33. super.onCreate(savedInstanceState);
  34. setContentView(R.layout.activity_main);
  35. initUI();
  36. visitWebBtn.setOnClickListener(new View.OnClickListener() {
  37. @Override
  38. public void onClick(View v) {
  39. // TODO Auto-generated method stub
  40. showImageView.setVisibility(View.GONE);
  41. showTextView.setVisibility(View.VISIBLE);
  42. Thread visitBaiduThread = new Thread(new VisitWebRunnable());
  43. visitBaiduThread.start();
  44. try {
  45. visitBaiduThread.join();
  46. if(!resultStr.equals("")){
  47. showTextView.setText(resultStr);
  48. }
  49. } catch (InterruptedException e) {
  50. // TODO Auto-generated catch block
  51. e.printStackTrace();
  52. }
  53. }
  54. });
  55. downImgBtn.setOnClickListener(new View.OnClickListener() {
  56. @Override
  57. public void onClick(View v) {
  58. // TODO Auto-generated method stub
  59. showImageView.setVisibility(View.VISIBLE);
  60. showTextView.setVisibility(View.GONE);
  61. String imgUrl = "http://www.shixiu.net/d/file/p/2bc22002a6a61a7c5694e7e641bf1e6e.jpg";
  62. new DownImgAsyncTask().execute(imgUrl);
  63. }
  64. });
  65. }
  66. @Override
  67. public boolean onCreateOptionsMenu(Menu menu) {
  68. // Inflate the menu; this adds items to the action bar if it is present.
  69. getMenuInflater().inflate(R.menu.main, menu);
  70. return true;
  71. }
  72. public void initUI(){
  73. showTextView = (TextView)findViewById(R.id.textview_show);
  74. showImageView = (ImageView)findViewById(R.id.imagview_show);
  75. downImgBtn = (Button)findViewById(R.id.btn_download_img);
  76. visitWebBtn = (Button)findViewById(R.id.btn_visit_web);
  77. }
  78. /**
  79. * 获取指定URL的响应字符串
  80. * @param urlString
  81. * @return
  82. */
  83. private String getURLResponse(String urlString){
  84. HttpURLConnection conn = null; //连接对象
  85. InputStream is = null;
  86. String resultData = "";
  87. try {
  88. URL url = new URL(urlString); //URL对象
  89. conn = (HttpURLConnection)url.openConnection(); //使用URL打开一个链接
  90. conn.setDoInput(true); //允许输入流,即允许下载
  91. conn.setDoOutput(true); //允许输出流,即允许上传
  92. conn.setUseCaches(false); //不使用缓冲
  93. conn.setRequestMethod("GET"); //使用get请求
  94. is = conn.getInputStream();   //获取输入流,此时才真正建立链接
  95. InputStreamReader isr = new InputStreamReader(is);
  96. BufferedReader bufferReader = new BufferedReader(isr);
  97. String inputLine  = "";
  98. while((inputLine = bufferReader.readLine()) != null){
  99. resultData += inputLine + "\n";
  100. }
  101. } catch (MalformedURLException e) {
  102. // TODO Auto-generated catch block
  103. e.printStackTrace();
  104. }catch (IOException e) {
  105. // TODO Auto-generated catch block
  106. e.printStackTrace();
  107. }finally{
  108. if(is != null){
  109. try {
  110. is.close();
  111. } catch (IOException e) {
  112. // TODO Auto-generated catch block
  113. e.printStackTrace();
  114. }
  115. }
  116. if(conn != null){
  117. conn.disconnect();
  118. }
  119. }
  120. return resultData;
  121. }
  122. /**
  123. * 从指定URL获取图片
  124. * @param url
  125. * @return
  126. */
  127. private Bitmap getImageBitmap(String url){
  128. URL imgUrl = null;
  129. Bitmap bitmap = null;
  130. try {
  131. imgUrl = new URL(url);
  132. HttpURLConnection conn = (HttpURLConnection)imgUrl.openConnection();
  133. conn.setDoInput(true);
  134. conn.connect();
  135. InputStream is = conn.getInputStream();
  136. bitmap = BitmapFactory.decodeStream(is);
  137. is.close();
  138. } catch (MalformedURLException e) {
  139. // TODO Auto-generated catch block
  140. e.printStackTrace();
  141. }catch(IOException e){
  142. e.printStackTrace();
  143. }
  144. return bitmap;
  145. }
  146. class VisitWebRunnable implements Runnable{
  147. @Override
  148. public void run() {
  149. // TODO Auto-generated method stub
  150. String data = getURLResponse("http://www.baidu.com/");
  151. resultStr = data;
  152. }
  153. }
  154. class DownImgAsyncTask extends AsyncTask<String, Void, Bitmap>{
  155. @Override
  156. protected void onPreExecute() {
  157. // TODO Auto-generated method stub
  158. super.onPreExecute();
  159. showImageView.setImageBitmap(null);
  160. showProgressBar();//显示进度条提示框
  161. }
  162. @Override
  163. protected Bitmap doInBackground(String... params) {
  164. // TODO Auto-generated method stub
  165. Bitmap b = getImageBitmap(params[0]);
  166. return b;
  167. }
  168. @Override
  169. protected void onPostExecute(Bitmap result) {
  170. // TODO Auto-generated method stub
  171. super.onPostExecute(result);
  172. if(result!=null){
  173. dismissProgressBar();
  174. showImageView.setImageBitmap(result);
  175. }
  176. }
  177. }
  178. /**
  179. * 在母布局中间显示进度条
  180. */
  181. private void showProgressBar(){
  182. progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleLarge);
  183. RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
  184. ViewGroup.LayoutParams.WRAP_CONTENT);
  185. params.addRule(RelativeLayout.CENTER_IN_PARENT,  RelativeLayout.TRUE);
  186. progressBar.setVisibility(View.VISIBLE);
  187. Context context = getApplicationContext();
  188. viewGroup = (ViewGroup)findViewById(R.id.parent_view);
  189. //      MainActivity.this.addContentView(progressBar, params);
  190. viewGroup.addView(progressBar, params);
  191. }
  192. /**
  193. * 隐藏进度条
  194. */
  195. private void dismissProgressBar(){
  196. if(progressBar != null){
  197. progressBar.setVisibility(View.GONE);
  198. viewGroup.removeView(progressBar);
  199. progressBar = null;
  200. }
  201. }
  202. }

AndroidManifest.xml里记得加访问网络的权限:

<uses-permission android:name="android.permission.INTERNET"/>

 

注意事项:

1、使用HttpURLConnection的步骤是先实例化一个URL对象,通过URL的openConnection实例化HttpURLConnection对象。然后设置参数,注意此时并没有发生连接。真正发生连接是在获得流时即conn.getInputStream这一句时,这点跟TCP Socket是一样的。并非阻塞在ServerSocket.accept()而是阻塞在获取流。所以在获取流之前应该设置好所有的参数。

2、Get和POST两种方式访问服务器,区别见链接1 链接2

3、[Android4.0后所有网络方面的操作都不能再主线程!!!]在获取网页响应字符串时本文代码使用了Thread,在下载图片时使用了AsyncTask,可以对比其使用的异同。很明显,AsyncTask更加方面。在onPreExecute和onPostExecute里可以很方面的做主线程UI的事。

4、在获取网页字符串时,使用了线程的Thread.join函数,这会使在onClick里在join处进行阻塞,直到Thread的run执行完才会进行判断,界面卡死。因此在实际开发中要尽量避免之中,解决方法是使用Thread+Handle的方式,或AsyncTask。实际上后者就是前者的封装。

5、访问图片比较简单,得到输入流后直接用BitmapFactory解析即可。

6、showProgressBar() 、dismissProgressBar()用来显示和隐藏下载图片时的提示框。

运行效果:

初始界面:

按下访问百度后:

按下下载图片后:

--------------------------------本文系原创,转载请注明作者:yanzi1225627

源码下载链接:http://download.csdn.net/detail/yanzi1225627/7104645

时间: 2024-10-21 06:04:47

Android网络:HTTP之利用HttpURLConnection访问网页、获取网络图片实例 (附源码)的相关文章

Android应用经典主界面框架之一:仿QQ (使用Fragment, 附源码)

最近反复研究日常经典必用的几个android app,从主界面带来的交互方式入手进行分析,我将其大致分为三类.今天记录第一种方式,即主界面下面有几个tab页,最上端是标题栏,tab页和tab页之间不是通过滑动切换的,而是通过点击切换tab页.早期这种架构一直是使用tabhost+activitygroup来使用,随着fragment的出现及google官方也大力推荐使用fragment,后者大有代替前者之势.本文也使用fragment进行搭建,标题中的"经典"指这种交互经典,非本文的代

leaflet结合geoserver利用WFS服务实现图层删除功能(附源码下载)

前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet 的插件库,非常有用 内容概览 leaflet结合geoserver利用WFS服务实现图层删除源代码demo下载 效果图如下: 本篇主要是在上一篇leaflet结合geoserver利用WFS服务实现图层新增功能(附源码下载)基础上实现的,leaflet通过调用geoserver发布的地图服务WFS来

openlayers6结合geoserver利用WFS服务实现图层删除功能(附源码下载)

内容概览 1.openlayers6结合geoserver利用WFS服务实现图层删除功能2.源代码demo下载 效果图如下: 本篇主要是在上一篇openlayers6结合geoserver利用WFS服务实现图层新增功能(附源码下载)基础上实现的,openlayers6通过调用geoserver发布的地图服务WFS来达到图层删除记录的目的.与GeoServer的WFS进行基于Rest交互关键就在于请求参数,值得注意的是这些请求最好采用POST方法发送.查询可以采用json,但增加,删除,修改都只能

Android应用系列:完美运行GIF格式的ImageView(附源码)

前言 我们都知道ImageView是不能完美加载Gif格式的图片,如果我们在ImageView中src指定的资源是gif格式的话,我们将会惊喜的发觉画面永远停留在第一帧,也就是不会有动画效果.当然,经过略加改造,我们是可以让gif在ImageView上完美加载的. 正文 Android给我们提供了一个Movie类,可以让我们实现加载gif格式资源的目标.我们需要导入android.graphics.Movie这个包,当然这个也是Android自带的.所以我们的主要方法是继承一个ImageView

【Android数据存储】SQLite使用实例(附源码)(转载)

原文地址:http://blog.csdn.net/wirelessqa/article/details/8583101 java当中提供了相当多的封装好的类来执行对SqlLite的操作,如: SQLiteDatabase 作为数据库操作的类,类似于C#当中我们自己写的helper,PS(java对此还真是高度封装) SQLiteOpenHelper 作为作为维护和管理数据库的基类实例: 会员信息管理 功能:1.查看数据库 2.清空数据库 3.增加会员 4.删除会员 5.更新会员 6.查找会员

leaflet结合geoserver利用WFS服务实现图层新增功能(附源码下载)

前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet 的插件库,非常有用 内容概览 leaflet结合geoserver利用WFS服务实现图层新增源代码demo下载 效果图如下: 本篇主要是leaflet通过调用geoserver发布的地图服务WFS来达到图层新增记录的目的.与GeoServer的WFS进行基于Rest交互关键就在于请求参数,值得注意的

Android学习笔记(十八)——使用意图筛选器和实现浏览网页(附源码)

使用意图筛选器 点击下载源码 1.创建一个Intents项目,给该项目添加一个新类,命名为MyBrowserActivity,在res/layout文件夹下新增一个browser.xml: 2.在AndroidManifest.xml文件中添加如下代码: 添加权限: <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="a

Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现 (附源码下载)

Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现 (附源码下载) POSTED ON 2014年6月27日 BY 天边的星星 本文内容: 1.横向ListView的所有实现思路; 2.其中一个最通用的思路HorizontalListView,并基于横向ListView开发一个简单的相册: 3.实现的横向ListView在点击.浏览时item背景会变色,并解决了listview里setSelected造成item的选择状态混乱的问题.

cesium结合geoserver利用WFS服务实现图层编辑(附源码下载)

前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内容概览 1.cesium结合geoserver利用WFS服务实现图层编辑功能2.源代码demo下载 效果图如下: 本篇主要是在上一篇cesium结合geoserver利用WFS服务实现图层新增(附源码下载)基础上实现的,cesium通过调用geoserver发布的地图服务WFS来达到图层编辑记录的目