在android中实现下载指定URL的图片并显示

好像很长时间没有写技术文章了,正好最近整理了一下前阵子做的android开发,在这里记录一下。这是一个简单的应用-下载指定URL的图片并显示。

说实在的这个应用没有什么特殊的地方,规模很小,用到的技术也很普通,但不失为一个很好的练手题材。既然是一个android的应用,那么里面多少涉及到了一些android开发的技术点,具体如下:

1. 界面-ImageSwitcher, ImageView, Gallery, Dialog, ProcessBar等等控件

2. 网络访问- HttpClient,  HttpEntity, HttpGet, HttpResponse等

3. 图片文件处理- Bitmap, BitmapFactory, ByteArrayOutputStream等

4. Java -如WeakReference等

5. Unit Test - ActivityInstrumentationTestCase2, LargeTest, KeyEvent等

因为没有准备去保存图片文件到外存,所以在例子中不涉及到数据库和磁盘文件读写的内容。下面我们按照软件工程的做法,先进行一下需求分析的。

其实不复杂,稍微思考一下我们就能得到以下的基本需求:

1. 输入URL

2. 下载图片

3. 显示图片

如果要进一步的优化这个应用,我们还需要做以下工作:

4. 良好的交互界面 - 如URL输入方式,错误处理,图片展示等等

5. 性能优化 - 内存使用率,网络延迟等

好了,需求确定下来以后,我们就要进入开发阶段了。实际上按照敏捷的开发方式来做,我们还要进一步的拆分需求。但自己做就不那么教条了^_^。根据TDD实践原则,那么我先来写一些测试。因为使用Eclipse来创建的android项目(如何搭建开发环境请上网搜,很多啦)。你可以在构建工程时同时构建测试工程,假设工程名为PicShow

这步完成后,我们会得到2个工程PicShow, PicShowTest。下面向PicShow的工程中添加代码了,在这之前我要给PicShowTest工程加入一些测试代码,

因为将来会有一个类叫PicShow用于显示下载的图片,所以我在setUp方法中这写:

        @Override
	protected void setUp() throws Exception {
		super.setUp();
		final PicShow a = getActivity();
		assertNotNull(a);
	}

 当你写完这段代码,编译一定不能通过,因为这个时候PicShow类还没定义, ^_^。那么我们可以借助Eclipse神奇的快速修正功能(ctrl+1)来新建一个类。然后创建一个TextBox用于输入URL, 一个Button处理点击事件。那在android里你有两种选择来创建控件,一是用代码生成一个实例,二是用layout文件。通常做法是选择后者(可以少写不少代码哦^_^),最后还需要一个imageView对象来显示图片。到这里就需要添加真正的测试代码了:

@LargeTest
public void testDownloadImage() throws Exception {
sendKeys(KeyEvent.KEYCODE_ENTER);
SystemClock.sleep(5000);
SimpleImageViewListAdapter adapter = (SimpleImageViewListAdapter)ga.getAdapter();
ImageView iv = (ImageView)adapter.getItem(0);
assertTrue( iv.getDrawable() != null);
}

在android的测试里面有几个annotation: @SmallTest, @MediumTest, @LargeTest。这些annotation有什么区别呢?

Feature Small Medium Large
Network access No localhost only Yes
Database No Yes Yes
File system access No Yes Yes
Use external systems No Discouraged Yes
Multiple threads No Yes Yes
Sleep statements No Yes Yes
System properties No Yes Yes
Time limit (seconds) 60 300 900+

主要是跟测试的内容有关系,我们在测试中要访问网络所以需要使用@LargeTest标志。接下来我们写一段下载图片的代码给按钮的Click事件调用:

public  Bitmap loadImageFromUrl(String url) throws Exception  {
final DefaultHttpClient client = new DefaultHttpClient();
final HttpGet getRequest = new HttpGet(url);

HttpResponse response = client.execute(getRequest);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.e("PicShow", "Request URL failed, error code =" + statusCode);
}

HttpEntity entity = response.getEntity();
if (entity == null) {
Log.e("PicShow", "HttpEntity is null");
}
InputStream is = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
is = entity.getContent();
byte[] buf = new byte[1024];
int readBytes = -1;
while ((readBytes = is.read(buf)) != -1) {
baos.write(buf, 0, readBytes);
}
} finally {
if (baos != null) {
baos.close();
}
if (is != null) {
is.close();
}
}
byte[] imageArray = baos.toByteArray();
return BitmapFactory.decodeByteArray(
imageArray, 0, imageArray.length);
}

这样我们一个简单的图片下载应用就搞定的。完整代码就在这里



posted @ 2011-10-19 21:33  moonz-wu  阅读(12829)  评论(0编辑  收藏  举报