android高分段进阶攻略(6)后台线程AsyncTask

又是一段悲伤的往事,一次面试过程中面试官用一口印度英语问我,Do you know AsyncTask?take a example for using it。由于南北地方差异,我听了好半天没听懂,就说我不知道,我没用过,哎,现在想想真难。

what is AsyncTask?AsyncTask是一种后台线程,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。

what is different between AsyncTask and Handler? Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。当你你从后台去更行界面的时候就应该考虑AsyncTask了。

AsyncTask的使用包括4个步骤:

(1)在onPreExecutive()方法中执行任何设置工作,此方法在主线程上执行。

(2)使用doInBackgroud()运行后台线程,线程创建全部在后台完成。

(3)使用publishProgress()和onProgressUpdate()更新进度。

(4)使用结果在onPostExecute()中更新用户界面,此方法在主线程中执行。

这样说有点官方化,我用例子来说明吧。

public class HttpActivity extends Activity {
	private DownloadImageTask diTask;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	}

	public void doClick(View view) {
		if (diTask != null) {
			AsyncTask.Status diStatus = diTask.getStatus();
			Log.v("doClick", "diTask status is " + diStatus);
			if (diStatus != AsyncTask.Status.FINISHED) {
				Log.v("doClick", "... no need to start a new task");
				return;
			}

		}
		diTask = new DownloadImageTask(this);
		diTask.execute("URL");
	}
}

主界面很简单,又是一个点击事件,然后执行diTask去下载URL上面的图片。

public class DownloadImageTask extends AsyncTask<String, Integer, Bitmap> {
	private Context mContext;

	DownloadImageTask(Context context) {
		mContext = context;
	}

	protected void onPreExecute() {

	}

	protected Bitmap doInBackground(String... urls) {
		return downloadImage(urls);
	}

	protected void onProgressUpdate(Integer... progress) {
		TextView mText = (TextView) ((Activity) mContext)
				.findViewById(R.id.text);
		mText.setText("Progress so far: " + progress[0]);
	}

	protected void onPostExecute(Bitmap result) {
		if (result != null) {
			ImageView mImage = (ImageView) ((Activity) mContext)
					.findViewById(R.id.image);
			mImage.setImageBitmap(result);
		} else {
			TextView errorMsg = (TextView) ((Activity) mContext)
					.findViewById(R.id.errorMsg);
			errorMsg.setText("Problem downloading image. Please try again later.");
		}
	}

	private Bitmap downloadImage(String... urls) {
		HttpClient httpClient = CustomHttpClient.getHttpClient();
		try {
			HttpGet request = new HttpGet(urls[0]);
			HttpParams params = new BasicHttpParams();
			HttpConnectionParams.setSoTimeout(params, 60000); // 1 minute
			request.setParams(params);

			publishProgress(25);

			HttpResponse response = httpClient.execute(request);

			publishProgress(50);

			byte[] image = EntityUtils.toByteArray(response.getEntity());

			publishProgress(75);

			Bitmap mBitmap = BitmapFactory.decodeByteArray(image, 0,
					image.length);

			publishProgress(100);

			return mBitmap;
		} catch (IOException e) {

			e.printStackTrace();
		}
		return null;
	}
}
然后就是实现AsyncTask,这里我还做了一个进度条,时时更新主界面UI的下载进度。

public class CustomHttpClient {
	private static HttpClient customHttpClient;

	/** A private Constructor prevents any other class from instantiating. */
	private CustomHttpClient() {
	}

	public static synchronized HttpClient getHttpClient() {
		if (customHttpClient == null) {
	        HttpParams params = new BasicHttpParams();
	        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
	        HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
	        HttpProtocolParams.setUseExpectContinue(params, true);
	        
	        ConnManagerParams.setTimeout(params, 1000);

	        HttpConnectionParams.setConnectionTimeout(params, 5000);
	        HttpConnectionParams.setSoTimeout(params, 10000);
	        
	        SchemeRegistry schReg = new SchemeRegistry();
	        schReg.register(new Scheme("http", 
	                        PlainSocketFactory.getSocketFactory(), 80));
	        schReg.register(new Scheme("https", 
	                        SSLSocketFactory.getSocketFactory(), 443));
	        ClientConnectionManager conMgr = new 
	                        ThreadSafeClientConnManager(params,schReg);
	        
	        customHttpClient = new DefaultHttpClient(conMgr, params);
		}
		return customHttpClient;
	}
}

这里是自定义HttpClient,最后点击就可以实现了网络异步图片下载,并且更新下载进度条,多也不知道该怎么讲述这个AsyncTask,只是知道它提供更方便的更新UI的方法,你可以从复写类里面看到,只要会用,知道怎么用,并且用在该用的地方就可以了,重要的是面试的时候知道这么个东西,反正我是很少用到。


android高分段进阶攻略(6)后台线程AsyncTask,布布扣,bubuko.com

android高分段进阶攻略(6)后台线程AsyncTask

上一篇:安卓 发送短信两种方式


下一篇:DPM 2012 SP1---恢复Exchange2013单用户邮箱