`
zhouxiaoli521
  • 浏览: 562220 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

AsyncTask(另一篇介绍asyncTask的文章 写的也很简洁易懂)

阅读更多
平时我们在开发Android程序时遇到较耗时任务的处理,如I/O访问的数据库操作、网络访问等情况时造成UI假死等问题,通过 AsyncTask可以很好的解决这个问题,就今天以在Android中执行Downloader.downloadFile(url),可能会堵塞整个界面。显然这会影响用户体验,我们如何解决这个问题呢?

  方法一、

  创建一个新的线程执行我们的任务,使用Thread类,在 run(){}中写入任务代码,比如:

  new Thread(new Runnable() {

  public void run() {

  Downloader.downloadFile(url);

  }

  }).start();

  但使用Thread会产生一些意想不到的问题,需要程序员用更多的代码手动的维护它。

  方法二: Android SDK为我们提供了一个后台任务的处理工具AsyncTask。AsyncTask就是一个封装过的后台任务类顾名思义就是异步任务,方便我们维护,Android开发网提示这样的好处可以解决一些线程安全问题,AsyncTask直接继承于Object类,位置为 android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载四个方法(至少重载一个)。

  三个泛型:

  Param ,任务执行器需要的数据类型

  Progress 后台计算中使用的进度单位数据类型

  Result 后台计算返回结果的数据类型

  有些参数是可以设置为不使用的,只要传递为Void型即可,比如AsyncTask

  四个步骤:

  onPreExecute(),执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件。

  doInBackground(Params...),后台进程执行的具体计算在这里实现,doInBackground(Params...)是AsyncTask的关键,此方法必须重载。在这个方法内可以使用 publishProgress(Progress...)改变当前的进度值。

  onProgressUpdate(Progress...),运行于UI线程。如果在doInBackground(Params...)中使用了publishProgress(Progress...),就会触发这个方法。在这里可以对进度条控件根据进度值做出具体的响应。

  onPostExecute(Result),运行于UI线程,可以对后台任务的结果做出处理,结果就是doInBackground(Params...)的返回值。此方法也要经常重载,如果Result为null表明后台任务没有完成(被取消或者出现异常)。
为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
  1) Task的实例必须在UI thread中创建
  2) execute方法必须在UI thread中调用
  3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
  4) 该task只能被执行一次,否则多次调用时将会出现异常



public class main extends Activity {
	ImageView imageView01;
	TextView textView;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		textView = (TextView) this.findViewById(R.id.TextView01);
		imageView01 = (ImageView) this.findViewById(R.id.ImageView01);
		GetImage getImage = new GetImage();
		getImage.execute("http://hi.csdn.net/attachment/201010/27/0_1288149117Yk8W.gif");
	}

	private class GetImage extends AsyncTask {

		public GetImage() {
			super();
			// TODO Auto-generated constructor stub
		}

		@Override
		protected void onCancelled() {
			Log.i("czb", "onCancelled is running...");

			super.onCancelled();
		}

		@Override
		protected void onPostExecute(Object result) {
			/*
			 * 此方法在主线程执行,任务执行的结果作为此方法的参数返回
			 */
			Log.i("czb", "onPostExecute is running...");
			Log.i("czb", "result == null ? " + (result == null));
			imageView01.setImageBitmap((Bitmap)result);
			
			super.onPostExecute(result);
		}

		@Override
		protected void onPreExecute() {
			/*
			 * 执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件
			 */
			Log.i("czb", "onPreExecute is running...");
			
			super.onPreExecute();
		}

		@Override
		protected void onProgressUpdate(Object... values) {
			/*
			 * 此方法在主线程执行,用于显示任务执行的进度。
			 */
			Log.i("czb", "onProgressUpdate is running...");
			// 由publishProgress传递的值
			Log.i("czb", "values " + values[0]);
			super.onProgressUpdate(values);
		}

		@Override
		protected Object doInBackground(Object... params) {
			/*
			 * 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。
			 * 在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
			 */
			Log.i("czb", "doInBackground is running...");
			
			try {
				Bitmap bitmap;
				HttpClient client = new DefaultHttpClient();
				// params[0]代表连接的url
				URI uri = URI.create((String) params[0]);
				HttpGet get = new HttpGet(uri);
				HttpResponse response = client.execute(get);
				HttpEntity entity = response.getEntity();
				long length = entity.getContentLength();
				Log.i("czb", "  " + length);
				InputStream in = entity.getContent();
				if (in != null) {
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					/*byte[] buf = new byte[128];
					int ch = -1;
					int count = 0;
					while ((ch = in.read(buf)) != -1) {
						baos.write(buf, 0, ch);
						count += ch;
						if (length > 0) {
							// 如果知道响应的长度,调用publishProgress()更新进度
							// onProgressUpdate读取进度
							publishProgress((int) ((count / (float) length) * 100));
						}
						// 为了在模拟器中清楚地看到进度,让线程休眠100ms
						//Thread.sleep(100);
					}*/
					bitmap = BitmapFactory.decodeStream(in);
					in.close();
					baos.close();
					return bitmap;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}

	}
}
  • 大小: 36 KB
  • 大小: 36 KB
分享到:
评论

相关推荐

    02_AsyncTask_简单演示AsyncTask异步操作

    AsyncTask_简单演示AsyncTask异步操作,写一个简单的AsyncTask异步操作解决上一篇文章提到的线程阻塞问题,对应我的博客《网易博客迁移:Android专题之AsyncTask(二)简单演示AsyncTask异步操作》,有问题欢迎留言...

    一个AsyncTask的Demo

    AsyncTask是Android平台中用于在后台执行耗时操作并更新UI的一种工具类。它主要设计用来简化异步处理,特别是那些需要与用户界面交互的任务。在这个"AsyncTask的Demo"中,我们将深入探讨AsyncTask的工作原理及其核心...

    AsyncTask类实例详解

    AsyncTask是Android中用于在后台线程执行耗时操作并更新UI的一种机制。它通过封装了线程管理和与主线程的交互,简化了在UI线程中处理异步任务的流程。下面我们将深入探讨AsyncTask的使用、原理以及如何更新UI。 ...

    Android AsyncTask 源码解析

    - **生命周期**:AsyncTask 的生命周期与 Activity 关联,如果 Activity 被销毁,那么与之相关的 AsyncTask 也可能会被取消。 - **内存泄漏**:由于 AsyncTask 与创建它的上下文有关,如果不正确地处理,可能会导致...

    Android AsyncTask Demo 自己参考网络写的学习 demo

    在Android开发中,AsyncTask是一种常用的工具类,用于在后台线程执行耗时操作,同时在UI线程更新进度或结果。这个“Android AsyncTask Demo”是开发者为了学习和理解AsyncTask工作原理而编写的示例代码。下面我们将...

    01_AsyncTask_演示线程阻塞

    在博客《Android专题之AsyncTask(一)基本概念介绍》中,我们详细分析了`AsyncTask`的优缺点,以及在实际项目中如何合理使用。通过学习这些内容,开发者可以更好地理解和运用`AsyncTask`,提高应用的响应速度和用户...

    android中AsyncTask的用法

    在Android应用开发中,AsyncTask是一个用于在后台线程执行耗时操作并更新UI的工具类,它是Android 1.5版本引入的。AsyncTask的设计初衷是为了简化异步编程,避免直接操作线程和Handler带来的复杂性。下面我们将详细...

    面向对象思想实现AsyncTask类的复用

    本篇文章将深入探讨如何利用面向对象的思想来实现AsyncTask类的复用,提高代码的可维护性和灵活性。 首先,我们需要理解AsyncTask的基本结构。AsyncTask包含三个泛型参数:Params、Progress和Result,分别对应于...

    android任务后台处理 asyncTask封装

    `AsyncTask`是Android提供的一种轻量级的异步处理机制,它能让我们在后台线程执行耗时操作,并在完成后更新主线程中的UI。下面我们将深入探讨`AsyncTask`的工作原理及其封装方法。 `AsyncTask`的核心在于三个泛型...

    Android AsyncTask异步处理下载网页

    Android提供了一种便捷的机制,名为`AsyncTask`,用于在后台线程执行这些任务,同时允许在主线程更新UI。`AsyncTask`是一个轻量级的框架,设计用来简化在Android应用程序中进行后台操作的过程。 `AsyncTask`包含三...

    AsyncTask结合HttpUrlConnection的例子

    在Android开发中,异步处理是非常重要的一环,特别是在与服务器进行数据交互时,为了保持UI线程的流畅性,避免出现"应用无响应"(ANR)的情况,开发者通常会使用`AsyncTask`。本例子是关于如何将`AsyncTask`与`...

    AsyncTask之cancel操作

    在Android开发中,AsyncTask是一个常用的工具类,用于在后台线程执行耗时操作,并在UI线程更新结果。本文将深入探讨`AsyncTask`的`cancel`操作,结合提供的链接文章《AsyncTask中cancel方法的误读》进行详细解析。 ...

    AsyncTask练习demo

    AsyncTask是Android中一个用于在后台线程执行耗时操作并更新UI的工具类,它非常适合处理...通过实践这个demo,你会对Android中的异步编程有更深入的认识,也能更好地掌握AsyncTask的使用技巧,提高应用程序的用户体验。

    异步任务AsyncTask

    在Android开发中,异步任务(AsyncTask)是一种常见的处理耗时操作的方式,尤其是在主线程中需要执行网络请求、数据库操作或大型数据处理时。它能够避免UI线程被阻塞,提供更好的用户体验。让我们深入了解一下`...

    AsyncTask的示例代码

    以上就是关于AsyncTask的基本介绍和使用方法,开发者可以根据实际需求灵活运用,以提升Android应用的用户体验。在实际开发中,理解并掌握AsyncTask的工作原理和最佳实践,对于编写高效、流畅的Android应用至关重要。

    AsyncTask源码

    最新AsyncTask源码

    Android 线程AsyncTask逐步在list中加入条目

    `AsyncTask`是Android提供的一种轻量级的多线程解决方案,特别适用于更新UI的操作。在这个例子中,我们将深入探讨如何使用`AsyncTask`来动态地在ListView中添加条目。 首先,让我们理解`AsyncTask`的基本结构。`...

    AsyncTask用法

    AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。  1) 子类化AsyncTask  2) 实现AsyncTask中定义的下面一个或几个方法  ...

    AsyncTask下载网络图片

    本篇文章将深入探讨如何利用`AsyncTask`实现网络图片的下载,并分享相关知识点。 首先,我们要理解`AsyncTask`的基本结构。`AsyncTask`有三个泛型参数,分别是`Params`、`Progress`和`Result`,分别代表输入参数...

    Android AsyncTask文章集合

    Android的AsyncTask是一个内置的异步执行框架,它允许开发者在主线程之外执行耗时操作,同时保持与主线程的通信,确保UI的流畅性。这个框架特别适用于那些需要进行短时间的后台处理并更新UI的任务,如网络请求、...

Global site tag (gtag.js) - Google Analytics