Android之利用HttpURLConnection下载图片

提起网络,我们就想起了HTTP,大多数Android应用程序也都是使用HTTP来发送和接收数据.

这里Android已经为我们提供了两种实现方式:HttpURLConnection和Apache的HttpClient,他们都支持Https、流下载和上传、以及设置超时等功能。Android官方文档推荐Android2.3版本以下用HttpClient Android2.3版本以上用HttpURLConnection。具体原因请参考Google开发者的博客:http://android-developers.blogspot.com/2011/09/androids-http-clients.html


今天我们来用HttpURLConnection方式完成一个Demo,效果是通过点击Button实现下载TextView中网址并呈现在ImageView中.

好了~现在就来一步一步实现:

首先,Android访问网络需要在AndroidManifest.xml中添加网络权限:

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

其次,在你连接网络的时候是不是还需要对网络进行检查,检查网络是否连接。这里Android为我们提供了两种方法getActiveNetworkInfo()和isConnected()。

在这里,我们需要什么时候检查网络是否连接呢?对滴~就是在Button点击事件中先检查网络

ConnectivityManager connMgr = (ConnectivityManager) 
        getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        // 获取数据
    } else {
        // 显示错误
    }

接下来,我们就可以获取网络上的数据了,但是这里有一个问题需要注意。由于网络中不可预知的情况或者硬盘读写速度再或者CPU等原因,这些都会引起未知的延迟,为了避免用户体验防止ANR。这里我们的网络操作应该在一个新的线程中去执行。这里我们用到了AsyncTask。


我们新建一个类DownloadWebPageText,这个类继承于AsyncTask,并且实现了AsyncTask的方法:doInBackground()和onPostExecute()。关于AsyncTask的简单介绍请参考我的另一篇博客:Android之AsyncTask介绍 。我们在doInBackground()执行网络操作:

// 使用AsyncTask创建一个独立于主UI线程之外的任务. 并使用URL字符串创建一个HttpUrlConnection对象。
	// 一旦连接建立,AsyncTask则将网页内容作为一个InputStream对象进行下载。
	// 最终,InputStream对象会被转换为一个字符串对象,并被AsyncTask的onPostExecute方法显示在UI上。
	private class DownloadWebpageText extends AsyncTask<String, Void, Bitmap> {

		@Override
		protected Bitmap doInBackground(String... params) {
			// TODO Auto-generated method stub
			// 参数来自execute(),调用params[0]得到URL
			try {
				return downloadUrl(params[0]);
			} catch (IOException e) {

			}
			return null;

		}

		@Override
		protected void onPostExecute(Bitmap bitmap) {
			// TODO Auto-generated method stub
			// 将InputStream转化为string
			ImageView imageView = (ImageView) findViewById(R.id.imageView1);

			imageView.setImageBitmap(bitmap);
		}

	}


其中在downloadUrl(params[0])方法中:

private Bitmap downloadUrl(String myurl) throws IOException {
		
		// 下載網址提供的圖片
		try {
			URL url = new URL(myurl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(10000 /* milliseconds */);
			conn.setConnectTimeout(15000 /* milliseconds */);
			conn.setRequestMethod("GET");
			conn.setDoInput(true);
			// 开始查询
			conn.connect();
			int response = conn.getResponseCode();
			Log.d(DEBUG_TAG, "The response is: " + response);
			is = conn.getInputStream();
			//将其转码或者转换为目标对象数据类型
			Bitmap bitmap = BitmapFactory.decodeStream(is);
			return bitmap;

			// 确保当app用完InputStream对象后关闭它。
		} finally {
			if (is != null) {
				is.close();
			}
		}
	}

这里我们使用GET方法来下载数据。当使用connect()方法后,我们调用getInputStream()来获得数据的输入流对象InputStream。

注意conn.getResponseCode()返回的是连接状态码。状态码为200的时候表示连接成功。

因为InputStream是字节流。通常都需要将其转码或者将其转换为目标对象数据类型。例如,这里我们将InputStream对象转换为Bitmap对像。


我们也可以将InputStream对象转换为String字符对象:

// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
    Reader reader = null;
    reader = new InputStreamReader(stream, "UTF-8");        
    char[] buffer = new char[len];
    reader.read(buffer);
    return new String(buffer);
}


最后来看一下Demo的效果图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值