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;
		}

	}
}
  • AsyncTask(另一篇介绍asyncTask的文章 写的也很简洁易懂)
  • 大小: 36 KB
  • AsyncTask(另一篇介绍asyncTask的文章 写的也很简洁易懂)
  • 大小: 36 KB
  • AsyncTask(另一篇介绍asyncTask的文章 写的也很简洁易懂)

你可能感兴趣的:(thread,android,工作,UI,OS)