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

               

 前文所示的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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/parent_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <FrameLayout        android:layout_width="match_parent"        android:layout_height="match_parent" >        <TextView            android:id="@+id/textview_show"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="@string/hello_world" />        <ImageView            android:id="@+id/imagview_show"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center" />    </FrameLayout>    <Button        android:id="@+id/btn_visit_web"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_alignParentLeft="true"        android:text="访问百度" />    <Button         android:id="@+id/btn_download_img"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_toRightOf="@id/btn_visit_web"        android:text="下载图片"/></RelativeLayout>

MainActivity.java

package org.yanzi.httpurlconnection;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.view.Menu;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.RelativeLayout;import android.widget.TextView;public class MainActivity extends Activity { Button visitWebBtn = null; Button downImgBtn = null; TextView showTextView = null; ImageView showImageView = null; String resultStr = ""; ProgressBar progressBar = null; ViewGroup viewGroup = null@Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  initUI();  visitWebBtn.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    // TODO Auto-generated method stub    showImageView.setVisibility(View.GONE);    showTextView.setVisibility(View.VISIBLE);    Thread visitBaiduThread = new Thread(new VisitWebRunnable());    visitBaiduThread.start();    try {     visitBaiduThread.join();     if(!resultStr.equals("")){      showTextView.setText(resultStr);     }    } catch (InterruptedException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }   }  });  downImgBtn.setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    // TODO Auto-generated method stub    showImageView.setVisibility(View.VISIBLE);    showTextView.setVisibility(View.GONE);    String imgUrl = "http://www.shixiu.net/d/file/p/2bc22002a6a61a7c5694e7e641bf1e6e.jpg";    new DownImgAsyncTask().execute(imgUrl);   }  }); } @Override public boolean onCreateOptionsMenu(Menu menu) {  // Inflate the menu; this adds items to the action bar if it is present.  getMenuInflater().inflate(R.menu.main, menu);  return true; } public void initUI(){  showTextView = (TextView)findViewById(R.id.textview_show);  showImageView = (ImageView)findViewById(R.id.imagview_show);  downImgBtn = (Button)findViewById(R.id.btn_download_img);  visitWebBtn = (Button)findViewById(R.id.btn_visit_web); } /**  * 获取指定URL的响应字符串  * @param urlString  * @return  */ private String getURLResponse(String urlString){  HttpURLConnection conn = null; //连接对象  InputStream is = null;  String resultData = "";  try {   URL url = new URL(urlString); //URL对象   conn = (HttpURLConnection)url.openConnection(); //使用URL打开一个链接   conn.setDoInput(true); //允许输入流,即允许下载   conn.setDoOutput(true); //允许输出流,即允许上传   conn.setUseCaches(false); //不使用缓冲   conn.setRequestMethod("GET"); //使用get请求   is = conn.getInputStream();   //获取输入流,此时才真正建立链接   InputStreamReader isr = new InputStreamReader(is);   BufferedReader bufferReader = new BufferedReader(isr);   String inputLine  = "";   while((inputLine = bufferReader.readLine()) != null){    resultData += inputLine + "\n";   }  } catch (MalformedURLException e) {   // TODO Auto-generated catch block   e.printStackTrace();  }catch (IOException e) {   // TODO Auto-generated catch block   e.printStackTrace();  }finally{   if(is != null){    try {     is.close();    } catch (IOException e) {     // TODO Auto-generated catch block     e.printStackTrace();    }   }   if(conn != null){    conn.disconnect();   }  }  return resultData; } /**  * 从指定URL获取图片  * @param url  * @return  */ private Bitmap getImageBitmap(String url){  URL imgUrl = null;  Bitmap bitmap = null;  try {   imgUrl = new URL(url);   HttpURLConnection conn = (HttpURLConnection)imgUrl.openConnection();   conn.setDoInput(true);   conn.connect();   InputStream is = conn.getInputStream();   bitmap = BitmapFactory.decodeStream(is);   is.close();  } catch (MalformedURLException e) {   // TODO Auto-generated catch block   e.printStackTrace();  }catch(IOException e){   e.printStackTrace();  }  return bitmap; } class VisitWebRunnable implements Runnable{  @Override  public void run() {   // TODO Auto-generated method stub   String data = getURLResponse("http://www.baidu.com/");   resultStr = data;  } } class DownImgAsyncTask extends AsyncTask<String, Void, Bitmap>{  @Override  protected void onPreExecute() {   // TODO Auto-generated method stub   super.onPreExecute();   showImageView.setImageBitmap(null);   showProgressBar();//显示进度条提示框  }  @Override  protected Bitmap doInBackground(String... params) {   // TODO Auto-generated method stub   Bitmap b = getImageBitmap(params[0]);   return b;  }  @Override  protected void onPostExecute(Bitmap result) {   // TODO Auto-generated method stub   super.onPostExecute(result);   if(result!=null){    dismissProgressBar();    showImageView.setImageBitmap(result);   }  } } /**  * 在母布局中间显示进度条  */ private void showProgressBar(){  progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleLarge);  RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,    ViewGroup.LayoutParams.WRAP_CONTENT);  params.addRule(RelativeLayout.CENTER_IN_PARENT,  RelativeLayout.TRUE);  progressBar.setVisibility(View.VISIBLE);  Context context = getApplicationContext();  viewGroup = (ViewGroup)findViewById(R.id.parent_view);  //  MainActivity.this.addContentView(progressBar, params);  viewGroup.addView(progressBar, params);   } /**  * 隐藏进度条  */ private void dismissProgressBar(){  if(progressBar != null){   progressBar.setVisibility(View.GONE);   viewGroup.removeView(progressBar);   progressBar = null;  } }}

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()用来显示和隐藏下载图片时的提示框。

运行效果:

初始界面:

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


按下访问百度后:

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


按下下载图片后:

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

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

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


           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow