Blog / 阅读

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

by admin on 2014-03-27 10:50:21 in ,



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


[java] view plaincopy
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 Serializable与Parcelable原理与区别

下一篇:Android:android:listSelector="#00000000" 与 android:listSelector="

评论

写评论

* 必填.

分享

栏目

赞助商


热门文章

Tag 云