`
cai75951577
  • 浏览: 9244 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

转:Android List列表网络资源异步调用

阅读更多

Android List列表网络资源异步调用

引言

曾经我在eoe上发了一篇帖子,关于List网络图片异步调用的,后来好多朋友给我留言、发站内消息索要要代码和具体实现方式,当时我也一并答应了,但苦于一直抽不出来时间,且要的人越来越多,挨个发实在麻烦,一直拖到今天。实在抱歉。

今天下午有点时间,我就在此整理整理,尽量详细的写出来,有疑问的可以在文章后方留言。

概要

首先大家都知道,有时候一个List(列表)里会用到网络图片之类的资源,应用有时会根据服务器提供的数据去调用并显示在List里,但如果一次性全部读取效率可想而知。这样我们就需要一个机制,让程序去获取数据量较小的文字简介之类的信息,同时在后台异步获取网络/服务器上数据量较庞大的数据资源,例如图片。

解决这个需求当然Android是有很多解决方案的。最容易维护,代码量最小且封装效率最好的实现方式是使用AsyncTask。使用匿名线程的话第一开销较大,不方便管理,且更新UI必须要引入handler,相当繁杂且代码会显的非常臃肿。

AsyncTask

首先AsyncTask是一个抽象类,子类继承AsyncTask必须实现其抽象方法doInBackground(Params…)。同时我们还需要实现onPostExecute(Result),因为结果会在Result中返回。

AsyncTask的生命周期

AsyncTask的生命周期分为四部分,每部分对应一回调方法,我们只需实现这些方法中的某些需要用到的方法。程序执行过程中这些会自动调用它们。

  • onPreExecute():任务执行之前执行,可在这显示进度条。
  • doInBackground(Params…):后台执行,主要用于完成需要任务。执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
  • onProgressUpdate(Progress…):主线程执行,用于显示任务执行的进度。
  • onPostExecute(Result):主线程执行,任务执行的结果作为此方法的参数返回。

AsyncTask中的三种泛型

AsyncTask中的三种泛型类型为Params、Progress、Result。

  • Params:启动任务参数,比如请求的资源地址。
  • Progress:顾名思义,后台任务执行的百分比。
  • Result:后台执行任务返回的结果。

AsyncTask的执行

AsyncTask只能在在主线程中创建实例,创建实例后使用execute(params)执行。任务仅会执行一次,如果想再调用就必须创建新的实例。

具体实现

首先我们先继承实现AsyncTask,然后在主线程的getView()里创建其实例execute().

1、实现AsyncTask

public class DownImageTask extends AsyncTask {
	private ImageView gView;
 
	protected Bitmap doInBackground(ImageView... views) {
		Bitmap bmp = null;
		ImageView view = views[0];
		HotelListData.Item item;
		// 根据iconUrl获取图片并渲染,iconUrl的url放在了view的tag中。
		if (view.getTag() != null) {
			try {
				item = (HotelListData.Item) view.getTag();
				URL url = new URL(item.getI().toString());
				HttpURLConnection conn = (HttpURLConnection) url
						.openConnection();
				conn.setDoInput(true);
				conn.connect();
				InputStream stream = conn.getInputStream();
				bmp = BitmapFactory.decodeStream(stream);
				Data.imageMap.put(item.getId(), bmp);
				stream.close();
			} catch (Exception e) {
				Log.v("img", e.getMessage());
				return null;
			}
		}
		this.gView = view;
		return bmp;
	}
 
	protected void onPostExecute(Bitmap bm) {
		if (bm != null) {
			this.gView.setImageBitmap(bm);
			this.gView = null;
		}
	}

2、在UI主线程中创建其实例并execute()执行

HotelListData dlData = new HotelListData();
HotelListData.Item item = dlData.new Item();
 
item = (HotelListData.Item) infoVector.getLs().elementAt(position);
holder.text0.setText(item.getN());
 
holder.star.setImageDrawable(getResources().getDrawable(
		imageIndex[Integer.parseInt(item.getS().toString())]));
 
holder.text2.setText(item.getP());
holder.text3.setText(item.getA());
 
if (item.getI() != null && (!item.getI().equals(""))) {
	Bitmap bm = returnBitMap(item.getId());
	if (bm != null) {
		holder.image.setImageBitmap(bm);
	} else {
		if (!holder.image.isDrawingCacheEnabled()
				|| !holder.image.getTag().equals(item.getI())) {
			holder.image.setImageResource(R.drawable.img_loading);
			holder.image.setTag(item);
			try {
				new DownImageTask().execute(holder.image);
				holder.image.setDrawingCacheEnabled(true);
			} catch (Exception e) {
				Log.e("error",
						"RejectedExecutionException in content_img: "
								+ item.getI());
			}
		}
	}
}

简要

首先创建了DownImageTask,该类继承实现了AsyncTask的doInBackground()和onPostExecute(),如上面所介绍,当在getView中创建实例并execute()传入需要获取资源地址URL(地址在TAG中)执行异步线程任务后,程序首先调用doInBackground()。

doInBackground()从传入的Image TAG中获取资源的URL地址进行图片的获取,获取完毕Retrun结果给onPostExecute(),onPostExecute()里再去做相应的结果处理。

最后实现效果

(图片是以前上传在eoe的图,被打了水印)

一开始用其他图片代替,我这直接仿照Google Adnroid Market用的灰色小静态图片(当然你也可以用圆的那种等待进度条动态图片,实现方式前面说过,实现onProgressUpdate(Progress…))

获取完毕后刷新替换(用的Wifi,另外截图软件反应慢,截个图真不容易)

总结

最后总结下思路,无外乎就是先用其他静态图片或者动态展示,后台异步获取图片后替换刷新。(另外最好像我一样弄个Catch(缓存)机制,在获取图片后Catch起来,以后获取先检测是否获取过,如果获取过就直接调用显示,检测标识就是上面放在Image TAG里的URL地址,程序关闭时释放Catch,当然你也可以存起来,看你的需求了)

原文地址:

http://www.jyasa.com/index.php/2010/07/android-list%E5%88%97%E8%A1%A8%E7%BD%91%E7%BB%9C%E8%B5%84%E6%BA%90%E5%BC%82%E6%AD%A5%E8%B0%83%E7%94%A8/

分享到:
评论

相关推荐

    Android获取Wifi列表

    在Android系统中,获取Wi-Fi列表是开发移动应用时常见的需求,这主要涉及到与网络连接相关的API交互。本文将详细讲解如何在Android中获取Wi-Fi列表,并根据信号强度来显示不同的网络图标。 首先,要获取Wi-Fi列表,...

    android Gallery实现异步加载网络图片 并只加载当前停止页面图.zip

    总的来说,这个`android Gallery实现异步加载网络图片 并只加载当前停止页面图`的示例展示了如何在Android应用中高效地处理大量网络图片的加载,通过异步加载和滚动监听,实现了只加载当前展示图片的策略,提升了...

    ListViewWithAsync:在列表视图中加载异步图像

    为了解决这个问题,我们可以采用异步加载策略,如“ListViewWithAsync”项目所示,它演示了如何在ListView中高效地加载网络或本地资源的图像。 【描述】:“ListViewWithAsync在test2上提交,使用齐射(Firing)...

    Android成功调用REST WebService

    在Android开发中,调用REST WebService是一种常见的数据交互方式,尤其在移动应用与服务器端进行数据交换时。REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,允许...

    Android 异步加载显示 Loader 自定义Loader

    本教程将详细介绍如何使用自定义Loader实现异步加载,特别是加载网络图片。 首先,Loader是ContentProvider的一部分,它处理数据的加载和刷新,同时管理生命周期,与Activity或Fragment的生命周期保持一致。Loader...

    Android异步任务处理之AsyncTaskLoader的使用

    在Android应用开发中,异步任务处理是必不可少的一部分,它能确保UI线程不被阻塞,提供良好的用户体验。AsyncTaskLoader是Android SDK提供的一种异步加载数据的工具,尤其适用于数据频繁变化并且需要在后台持续监控...

    Android学习笔记(三二):线程:后台异步任务AsyncTask.doc

    在Android中,由于UI操作必须在主线程中进行,因此需要异步处理来避免阻塞用户界面。AsyncTask就是为此目的设计的,它提供了四个关键的方法,使得开发者可以方便地执行后台任务并在适当的时候更新UI。 1. **...

    android list demo1

    最后,如果你的列表数据是从网络或数据库获取的,你可能需要实现异步加载,例如使用AsyncTask或者现代的LiveData、ViewModel和Repository模式。这将确保在数据加载完成后再更新ListView,防止用户界面卡顿。 总之,...

    Android 工具类android-common

    在Android开发过程中,工具类(Utility Classes)是开发者经常使用的代码模块,它们包含了各种实用功能,可以帮助我们简化常见的编程任务。"Android 工具类android-common"是一个专门为Android平台设计的集合,它...

    3G Android实战课程(.list文件)

    在描述中提到的“3G Android实战课程(.list文件)”很可能是一份学习资源清单或者课程大纲,其中包含了关于3G技术在Android平台上的实际应用和开发的学习路径。.list文件通常是一个文本文件,用于存储一系列项目或...

    Android:ProgressBar的初步学习

    7. **异步任务中的应用**:在执行耗时操作如网络请求或文件操作时,可以显示进度条,然后在任务完成时隐藏它。通过`AsyncTask`或者`Handler`来更新进度。 8. **自定义进度条**:如果需要更个性化的进度条,可以通过...

    必看Android 500道高薪面试题集

    32. Android中避免ForceClose的策略:通过异常捕获、异步处理、优化代码逻辑等方式减少程序崩溃。 33. ContentProvider实现数据共享的机制:作为数据源,提供数据给其他应用访问。 34. Service和Thread的区别:...

    Android学习笔记

    8. **资源管理**:Android应用的资源如图片、字符串、颜色值等应存储在res目录下,便于根据不同设备和语言进行适配。 9. **数据持久化**:SQLite数据库用于存储结构化的数据,SharedPreferences用于保存轻量级配置...

    ImageAndTextListview:Android 图像和文本列表视图

    6. **异步加载图像**:在实际应用中,由于网络图片的加载可能较慢,因此需要使用异步加载库,如Glide或Picasso,来在后台线程加载图片,防止阻塞UI主线程。 7. **XML 布局**:每个列表项通常有自己的XML布局文件,...

    基于 AList api 开发的 Android 和 iOS 客户端.zip

    标题 "基于 AList API 开发的 Android 和 iOS 客户端.zip" 提示我们这是一个包含 Android 和 iOS 应用程序源代码的压缩包,这些应用程序是利用 AList API 构建的。AList API 可能是一个提供数据访问、列表管理或者...

    Android_FTP.zip_android_android ftp_ftp android

    连接成功后,可以进行文件操作,如listFiles获取服务器目录列表,uploadFile和downloadFile进行文件上传和下载,renameFile重命名文件,deleteFile删除文件等。 5. 主动模式与被动模式: 在Android设备上,由于可能...

    Android开发之二级联动下拉框

    在Android Studio中,开发者可以在布局文件中添加`Spinner`元素,并通过`android:entries`属性引用一个数组资源,该数组资源包含了所有可选的项目。对于二级联动,你需要两个`Spinner`,分别代表省份和城市。你可以...

    android Gallery实现异步加载网络图片 并只加载当前停止页面图.rar

    `Gallery`是Android提供的一个视图组件,它继承自`AbsSpinner`,并提供了一个水平滚动的列表。通过监听`OnItemSelectedListener`事件,我们可以知道用户在`Gallery`中的选择变化,以便加载相应的图片。 其次,我们...

    Android 电影简介分析源码.zip源码资源下载

    该资源是一个针对Android平台的电影简介分析应用的源代码,主要使用了Java语言进行开发,并且可能涉及到Apache的相关库或工具。在这个项目中,开发者可能实现了对电影数据的抓取、解析、展示以及分析功能。下面我们...

    【Android开发学习29】界面控件之列表控件(ListView)--显示图片和文本

    这可能涉及到网络请求(例如,使用Glide或Picasso库)或从本地资源加载。同时,设置TextView的文本内容。 4. **关联ListView与Adapter**: 在Activity中,通过调用ListView的`setAdapter()`方法,将自定义Adapter...

Global site tag (gtag.js) - Google Analytics