【Android】Android中AsyncTask的定义和使用方法
AsyncTask介绍
Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。
AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。
MainActivity.Java
package com.example.asyncdemo; import java.net.URI; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.Toast; public class MainActivity extends Activity { private Button mDownloadBtn; private Button mCancelBtn; private ImageView mImage1; private ImageView mImage2; private ProgressBar mProgress1; private ProgressBar mProgress2; private GetLogoFromInternet mTask; private String TAG = "GetLogoFromInternet"; // 一个异步任务的执行一般包括以下几个步骤: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initComponent(); } private void initComponent() { mDownloadBtn = (Button) findViewById(R.id.button1); mDownloadBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mTask = new GetLogoFromInternet(); // 1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。 mTask.execute( "http://d.hiphotos.baidu.com/image/pic/item/caef76094b36acaf8ded6c2378d98d1000e99ce4.jpg", "http://e.hiphotos.baidu.com/image/pic/item/00e93901213fb80e2f00716233d12f2eb83894b5.jpg"); } }); mCancelBtn = (Button) findViewById(R.id.button2); mCancelBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub mTask.cancel(true); } }); mImage1 = (ImageView) findViewById(R.id.imageView1); mImage2 = (ImageView) findViewById(R.id.imageView2); mProgress1 = (ProgressBar) findViewById(R.id.progressBar1); mProgress2 = (ProgressBar) findViewById(R.id.progressBar2); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } class GetLogoFromInternet extends AsyncTask<String, Integer, Bitmap> { private Bitmap bitmap = null; // 2.onPreExecute(),在execute(Params...params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。 //onPreExecute方法用于在执行后台任务前做一些UI操作 @Override protected void onPreExecute() { mImage1.setImageBitmap(null); mImage2.setImageBitmap(null); mProgress1.setProgress(0); mProgress2.setProgress(0); Log.e(TAG, "onPreExecute"); } // 3.doInBackground(Params...params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。 // 在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。 @Override protected Bitmap doInBackground(String... params) { publishProgress(0, 0); HttpClient hc = new DefaultHttpClient(); publishProgress(30, 0); HttpGet hg = new HttpGet(); Bitmap bitmap2 = null; try { hg.setURI(new URI(params[0])); HttpResponse response = hc.execute(hg); bitmap = BitmapFactory.decodeStream(response.getEntity() .getContent()); publishProgress(100, 30); hg.setURI(new URI(params[1])); HttpResponse response2 = hc.execute(hg); bitmap2 = BitmapFactory.decodeStream(response2.getEntity() .getContent()); } catch (Exception e) { Log.e(TAG, "" + e.getMessage()); } publishProgress(100, 100); Log.e(TAG, "doInBackground"); // mImage1.setImageBitmap(bitmap);//error return bitmap2; } // 4.onProgressUpdate(Progress... values),在调用publishProgress(Progress...values)时, // 此方法被执行,直接将进度信息更新到UI组件上。 @Override protected void onProgressUpdate(Integer... values) { mProgress1.setProgress(values[0]); mProgress2.setProgress(values[1]); Log.e(TAG, "onProgressUpdate"); } // 5.onPostExecute(Result result),当后台操作结束时, // 此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。 @Override protected void onPostExecute(Bitmap result) { if (result != null) { mImage1.setImageBitmap(bitmap); mImage2.setImageBitmap(result); Toast.makeText(MainActivity.this, "get image from network successful", Toast.LENGTH_SHORT) .show(); } else { Toast.makeText(MainActivity.this, "get image from network error", Toast.LENGTH_SHORT) .show(); } Log.e(TAG, "onPostExecute"); } //onCancelled方法用于在取消执行中的任务时更改UI @Override protected void onCancelled() { mProgress1.setProgress(0); mProgress2.setProgress(0); Log.e(TAG, "onCancelled"); } } // 在使用的时候,有几点需要格外注意: // 1.异步任务的实例必须在UI线程中创建。 // 2.execute(Params... params)方法必须在UI线程中调用。 // 3.不要手动调用onPreExecute(),doInBackground(Params... // params),onProgressUpdate(Progress... values),onPostExecute(Result // result)这几个方法。 // 4.不能在doInBackground(Params... params)中更改UI组件的信息。 // 5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。 }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" android:orientation="vertical" > <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical" > <ProgressBar android:id="@+id/progressBar1" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/imageView1" android:layout_width="150dp" android:layout_height="150dp" /> <ProgressBar android:id="@+id/progressBar2" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" /> <ImageView android:id="@+id/imageView2" android:layout_width="150dp" android:layout_height="150dp" /> <Button android:id="@+id/button1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="下载图片" /> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="取消下载" /> </LinearLayout> </ScrollView> </LinearLayout>
AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"/>
作者:xubuhang
出处:http://www.cnblogs.com/xubuhang/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。