对于图片的加载效果,见链接:[Android] PorterDuff使用实例----实现新浪微博图片下载效果
本文参考链接:http://developer.android.com/reference/android/os/AsyncTask.html
AsyncTask被设计成方便编写Thread与Handler交互的辅助类,几秒钟的背景耗时操作是理想的使用场合。
AsyncTask必须被子类化才能使用,在该过程中必须设定3个构造参数:
1.Params 往背景线程执行时的参数类型
2.Progress 背景线程发布任务进度的参数类型
3.Result 背景线程的运行后最后返回的结果的参数类型
如果不需要声明参数类型,可以使用"Void"进行替代。
通常子类化声明代码:
- public class DownloadImgTask extends AsyncTask<String, Float, Bitmap>
不需要参数的声明代码:
- public class DownloadImgTask extends AsyncTask<Void, Void, Void>
当一个AsyncTask被执行后,会有如下4个步骤:
1.onPreExecute() 在UI线程中调用。这个步骤通常用于一些准备操作,如显示一个进度条
2.doInBackground(Params ...) 当onPreExecute()执行完毕后,即被背景线程调用执行。这个步骤用于执行耗时的计算。方法中为不定参数,由外部调用AsyncTask.execute(Params...)时设定。本步骤运行的过程可以通过publishProgress(Progress...)发布到onProgressUpdate(Progress...)中,运行结果将return,后被传参至onPostExecute(Result)。
3.onProgressUpdate(Progress...) 当执行publishProgress(Progress...)后在UI线程中被调用。执行的时间是不确定的。
4.onPostExecute(Result) 在UI线程中被调用。参数为doInBackground(Params...)的运行结果。
在AsyncTask的执行过程中可以调用cancel(boolean),方法中的参数值为false时允许已经开始工作的背景线程继续工作至任务完成;为true时则强制停止。AsyncTask将不再调用onPostExecute(Result),取而代之的是调用onCancelled(Object)。为了确定当前的AsyncTask是否已经被cancelled,应该在doInBackground(Params...)方法中执行isCancelled()进行检查。
为了AsyncTask顺利工作,必须遵守线程规则:
1.AsyncTask必须在UI线程中被调用。JELLY_BEAN版本默认已经遵守此规则。
2.AsyncTask的实例必须在UI线程中被创建。
3.execute(Params...)必须在UI线程中被调用。
4.不允许手工调用以下方法:
onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)
5.AsyncTask的实例只能被执行一次。再次执行时将会抛出异常:
java.lang.IllegalStateException: Cannot execute task: the task is already running.
本文为Sodino所有,转载请注明出处:http://blog.csdn.net/sodino/article/details/7741674
Java代码贴上,XML请各位看官自行实现:
- ActAsyncTask.java
-
- package lab.sodino.asynctask;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
-
- public class ActAsyncTask extends Activity implements OnClickListener {
- private PorterDuffView pViewA, pViewB, pViewC, pViewD;
- public static final String[] STRING_ARR = {
- "http://developer.android.com/images/home/android-jellybean.png",//
- "http://developer.android.com/images/home/design.png",//
- "http://developer.android.com/images/home/google-play.png",//
- "http://developer.android.com/images/home/google-io.png" };
-
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- pViewA = (PorterDuffView) findViewById(R.id.pViewA);
- pViewA.setOnClickListener(this);
- pViewB = (PorterDuffView) findViewById(R.id.pViewB);
- pViewB.setOnClickListener(this);
- pViewC = (PorterDuffView) findViewById(R.id.pViewC);
- pViewC.setOnClickListener(this);
- pViewD = (PorterDuffView) findViewById(R.id.pViewD);
- pViewD.setOnClickListener(this);
- }
-
- public void onClick(View v) {
- if (v instanceof PorterDuffView) {
- PorterDuffView pdView = (PorterDuffView) v;
- if (pdView.isLoading() == false) {
- DownloadImgTask task = new DownloadImgTask(pdView);
- task.execute(STRING_ARR[pdView.getId() % STRING_ARR.length]);
- pdView.setPorterDuffMode(true);
- pdView.setLoading(true);
- pdView.setProgress(0);
- pdView.invalidate();
- }
- }
- }
- }
- DownloadImgTask.java
-
-
- package lab.sodino.asynctask;
-
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
-
- import org.apache.http.Header;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.ClientProtocolException;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.params.HttpParams;
-
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.AsyncTask;
-
-
-
-
-
- public class DownloadImgTask extends AsyncTask<String, Float, Bitmap> {
- private PorterDuffView pdView;
-
- public DownloadImgTask(PorterDuffView pdView) {
- this.pdView = pdView;
- }
-
-
- protected void onPreExecute() {
- LogOut.out(this, "onPreExecute");
- }
-
-
- protected Bitmap doInBackground(String... params) {
- LogOut.out(this, "doInBackground:" + params[0]);
- HttpClient httpClient = new DefaultHttpClient();
- HttpGet httpGet = new HttpGet(params[0]);
- InputStream is = null;
- ByteArrayOutputStream baos = null;
- try {
- HttpResponse httpResponse = httpClient.execute(httpGet);
- printHttpResponse(httpResponse);
- HttpEntity httpEntity = httpResponse.getEntity();
- long length = httpEntity.getContentLength();
- LogOut.out(this, "content length=" + length);
- is = httpEntity.getContent();
- if (is != null) {
- baos = new ByteArrayOutputStream();
- byte[] buf = new byte[128];
- int read = -1;
- int count = 0;
- while ((read = is.read(buf)) != -1) {
- baos.write(buf, 0, read);
- count += read;
- publishProgress(count * 1.0f / length);
- }
- LogOut.out(this, "count=" + count + " length=" + length);
- byte[] data = baos.toByteArray();
- Bitmap bit = BitmapFactory.decodeByteArray(data, 0, data.length);
- return bit;
- }
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if (baos != null) {
- baos.close();
- }
- if (is != null) {
- is.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return null;
- }
-
-
- protected void onProgressUpdate(Float... progress) {
-
- pdView.setProgress(progress[0]);
- }
-
-
- protected void onPostExecute(Bitmap bit) {
- LogOut.out(this, "onPostExecute");
- pdView.setPorterDuffMode(false);
- pdView.setLoading(false);
- pdView.setImageBitmap(bit);
- }
-
- protected void onCancelled() {
- LogOut.out(this, "DownloadImgTask cancel...");
- super.onCancelled();
- }
-
- private void printHttpResponse(HttpResponse httpResponse) {
- Header[] headerArr = httpResponse.getAllHeaders();
- for (int i = 0; i < headerArr.length; i++) {
- Header header = headerArr[i];
- LogOut.out(this, "name[" + header.getName() + "]value[" + header.getValue() + "]");
- }
- HttpParams params = httpResponse.getParams();
- LogOut.out(this, String.valueOf(params));
- LogOut.out(this, String.valueOf(httpResponse.getLocale()));
- }
- }
- PorterDuffView.java
-
- package lab.sodino.asynctask;
-
- import java.text.DecimalFormat;
-
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- import android.graphics.PorterDuff;
- import android.graphics.PorterDuffXfermode;
- import android.graphics.drawable.BitmapDrawable;
- import android.graphics.drawable.Drawable;
- import android.util.AttributeSet;
- import android.widget.ImageView;
-
-
-
-
-
-
-
- public class PorterDuffView extends ImageView {
-
- public static final int FG_HEIGHT = 1;
-
-
- public static final int FOREGROUND_COLOR = 0x77ff0000;
-
- public static final int TEXT_COLOR = 0xff7fff00;
-
- public static final int FONT_SIZE = 30;
- private Bitmap bitmapBg, bitmapFg;
- private Paint paint;
-
- private float progress;
-
- private int width, height;
-
- private DecimalFormat decFormat;
-
- private float txtBaseY;
-
- private boolean porterduffMode;
-
- private boolean loading;
-
- public PorterDuffView(Context context, AttributeSet attrs) {
- super(context, attrs);
- init(context, attrs);
- }
-
-
- private static Bitmap createForegroundBitmap(int w) {
- Bitmap bm = Bitmap.createBitmap(w, FG_HEIGHT, Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(bm);
- Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
- p.setColor(FOREGROUND_COLOR);
- c.drawRect(0, 0, w, FG_HEIGHT, p);
- return bm;
- }
-
- private void init(Context context, AttributeSet attrs) {
- if (attrs != null) {
-
-
-
-
-
-
-
-
-
-
-
-
- TypedArray typedArr = context.obtainStyledAttributes(attrs, R.styleable.porterduff_PorterDuffView);
- porterduffMode = typedArr.getBoolean(R.styleable.porterduff_PorterDuffView_porterduffMode, false);
- }
- Drawable drawable = getDrawable();
- if (porterduffMode && drawable != null && drawable instanceof BitmapDrawable) {
- bitmapBg = ((BitmapDrawable) drawable).getBitmap();
- width = bitmapBg.getWidth();
- height = bitmapBg.getHeight();
-
- bitmapFg = createForegroundBitmap(width);
- } else {
-
- porterduffMode = false;
- }
-
- paint = new Paint();
- paint.setFilterBitmap(false);
- paint.setAntiAlias(true);
- paint.setTextSize(FONT_SIZE);
-
-
-
- Paint.FontMetrics fontMetrics = paint.getFontMetrics();
-
-
- LogOut.out(this, "ascent:" + fontMetrics.ascent
-
- + " descent:" + fontMetrics.descent
-
- + " top:" + fontMetrics.top
-
- + " bottom:" + fontMetrics.bottom
-
- + " leading:" + fontMetrics.leading);
-
- txtBaseY = (height - fontMetrics.bottom - fontMetrics.top) / 2;
-
- decFormat = new DecimalFormat("0.0%");
- }
-
- public void onDraw(Canvas canvas) {
- if (porterduffMode) {
- int tmpW = (getWidth() - width) / 2, tmpH = (getHeight() - height) / 2;
-
- canvas.drawBitmap(bitmapBg, tmpW, tmpH, paint);
-
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
-
-
- int tH = height - (int) (progress * height);
- for (int i = 0; i < tH; i++) {
- canvas.drawBitmap(bitmapFg, tmpW, tmpH + i, paint);
- }
-
-
- paint.setXfermode(null);
- int oriColor = paint.getColor();
- paint.setColor(TEXT_COLOR);
- paint.setTextSize(FONT_SIZE);
- String tmp = decFormat.format(progress);
- float tmpWidth = paint.measureText(tmp);
- canvas.drawText(decFormat.format(progress), tmpW + (width - tmpWidth) / 2, tmpH + txtBaseY, paint);
-
- paint.setColor(oriColor);
- } else {
- LogOut.out(this, "onDraw super");
- super.onDraw(canvas);
- }
- }
-
- public void setProgress(float progress) {
- if (porterduffMode) {
- this.progress = progress;
-
- invalidate();
- }
- }
-
- public void setBitmap(Bitmap bg) {
- if (porterduffMode) {
- bitmapBg = bg;
- width = bitmapBg.getWidth();
- height = bitmapBg.getHeight();
-
- bitmapFg = createForegroundBitmap(width);
-
- Paint.FontMetrics fontMetrics = paint.getFontMetrics();
- txtBaseY = (height - fontMetrics.bottom - fontMetrics.top) / 2;
-
- setImageBitmap(bg);
-
-
- }
- }
-
- public boolean isLoading() {
- return loading;
- }
-
- public void setLoading(boolean loading) {
- this.loading = loading;
- }
-
- public void setPorterDuffMode(boolean bool) {
- porterduffMode = bool;
- }
- }