2012年2月7日 星期二

Android - AsyncTask

在處理秏時的Android程序時,User可能感覺到系統畫面停頓,感到不協調,甚至發生ANR的錯誤。因此,該耗時程序應另指派一執行緒負責維護運作進行。
PS. UI Thread 若執行5秒以上的工作會拋出ANR的錯誤     
     
AsyncTask執行上的重要方法
(1) onPreExecute( )                               =>    任務執行前呼叫此方法      
(2) doInBackground(Params... )           =>    執行任務工作
(3) onProgressUpdate(Progress... )      =>    顯示任務執行進度
(4) onPostExecute(Result)                    =>    任務執行完成會呼叫此方法        

AsyncTask定義了三種泛型
AsyncTask<Params, Progress, Result>
(1) Params:啟動任務執行的輸入參數,設定於 execute() 的參數型別
(2) Progress:幕後工作執行的百分比
(3) Result:後台執行任務最終返回的結果,設定於 onPostExecute() 的參數型別

    實作方法
    package com.test;

    import java.io.ByteArrayOutputStream;
    import java.io.InputStream;

    import org.apache.http.HttpEntity;
    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.app.Activity;
    import android.app.ProgressDialog;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.drawable.BitmapDrawable;
    import android.graphics.drawable.Drawable;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.ImageView;

    public class AsyncTeskProgress extends Activity
    {
    private Button Button01;
    private ImageView imageView01;
    private String imgURL = "http://vincentjava.skyhostsite.0lx.net/img/white.png";

        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
         
            Button01 = (Button) findViewById(R.id.Button01);
            imageView01 = (ImageView) findViewById(R.id.imageView01);
    Button01.setOnClickListener(new AsyncBtnOnClickListener());
        }
     
        private class AsyncBtnOnClickListener implements OnClickListener
    {
    @Override
    public void onClick(View view)
    {
    imageView01.setVisibility(View.VISIBLE);
    new AsyncTaskLoadImageProgress().execute(imgURL);
    }

    private class AsyncTaskLoadImageProgress extends AsyncTask<String,IntegerDrawable>
    {
    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute()
    {
    progressDialog = new ProgressDialog(AsyncTeskProgress.this);
    progressDialog.setTitle("ProgressDialog");
    progressDialog.setMessage("Wait!");
    progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressDialog.setCancelable(false);
    progressDialog.show();
    }

    @Override
    protected Drawable doInBackground(String... args)
    {
    try
    {
    // 1.取得 HttpEntity 實體
    HttpEntity entity = getHttpEntityByURL(args[0]);
    long length = entity.getContentLength();
    InputStream is = entity.getContent();

    // 2.資料讀取與接收
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buf = new byte[128];
    int ch = -1;
    int count = 0;

    while ((ch = is.read(buf)) != -1)
    {
    baos.write(buf, 0, ch);
    count += ch;

    if (length > 0)
    {
    publishProgress((int) ((count / (float) length) * 100));
    }
    }

    // 3.資料轉換 byte[]  -->  Bitmap  -->  Drawable
    byte[] b = baos.toByteArray();
    Bitmap bmp = BitmapFactory.decodeByteArray(b, 0, b.length);
    Drawable drawable = new BitmapDrawable(bmp);

    return drawable;

    }

    catch (Exception e)
    {
    e.printStackTrace();
    }

    return null;
    }

    @Override
    protected void onProgressUpdate(Integer... values)
    {
    // 更新進度
    progressDialog.setProgress(values[0]);
    }

    @Override
    protected void onPostExecute(Drawable resultImage)
    {
    progressDialog.dismiss();

    if (resultImage != null)
    {
    imageView01.setImageDrawable(resultImage);
    imageView01.setVisibility(View.VISIBLE);
    }
    }
    }
    }

    private HttpEntity getHttpEntityByURL(String url) throws Exception
    {
    HttpClient client = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);
    HttpResponse response = client.execute(get);
    HttpEntity entity = response.getEntity();
    return entity;
    }
    }


    執行結果如下

    沒有留言:

    張貼留言