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

来源:互联网 发布:雷霆vs勇士第六场数据 编辑:程序博客网 时间:2024/05/17 03:32

如前文所示的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?在CODE上查看代码片派生到我的代码片
  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.   
  12.     <FrameLayout  
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="match_parent" >  
  15.   
  16.         <TextView  
  17.             android:id="@+id/textview_show"  
  18.             android:layout_width="wrap_content"  
  19.             android:layout_height="wrap_content"  
  20.             android:text="@string/hello_world" />  
  21.   
  22.         <ImageView  
  23.             android:id="@+id/imagview_show"  
  24.             android:layout_width="wrap_content"  
  25.             android:layout_height="wrap_content"  
  26.             android:layout_gravity="center" />  
  27.     </FrameLayout>  
  28.   
  29.     <Button  
  30.         android:id="@+id/btn_visit_web"  
  31.         android:layout_width="wrap_content"  
  32.         android:layout_height="wrap_content"  
  33.         android:layout_alignParentBottom="true"  
  34.         android:layout_alignParentLeft="true"  
  35.         android:text="访问百度" />  
  36.     <Button   
  37.         android:id="@+id/btn_download_img"  
  38.         android:layout_width="wrap_content"  
  39.         android:layout_height="wrap_content"  
  40.         android:layout_alignParentBottom="true"  
  41.         android:layout_toRightOf="@id/btn_visit_web"  
  42.         android:text="下载图片"/>  
  43.   
  44. </RelativeLayout>  

MainActivity.java

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

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

0 0
原创粉丝点击