天天看點

Android多線程程式設計AsyncTask                                        Android多線程程式設計AsyncTask

                                        Android多線程程式設計AsyncTask

        在android開發中,多線程占着重要的比例。通常 耗時 的邏輯操作 一般都會開辟出新的線程來處理  比如說 網絡請求 是最常見的一種需要開辟出另一道線程來處理,因為UI線程不能中性網絡操作,網絡操作比較耗時。      AsyncTask,是android提供的輕量級的異步類,可以直接繼承AsyncTask,在類中實作異步操作,并提供接口回報目前異步執行的程度(可以通過接口實作UI進度    更新),最後回報執行的結果給UI主線程.

        接下來介紹一下 Android多線程程式設計AsyncTask.                

                        AsyncTask<Params, Progress, Result>                提供了泛型。要運用asynctask 就必須要知道Params, Progress, Result 三個參數的含義               Params:  啟動任務執行的輸入參數,比如說Http請求的URL                   Progress: 背景執行的進度 ,一般用在進度條對話框中

               Result:最後傳回的結果,如果說請求一張圖檔,最後包裝成Bitmap 那就是傳回bitmap類型。String等類型也                             是可以。

               知道了參數,接下來看下AsyncTask  裡面執行方法的順序。      

@Override
	protected void onPreExecute()
	{
	    super.onPreExecute();
	    dialog.show();

	}
           

                   第一步:從方法名Pre可以看出 這個是預備英文的縮寫,也就是說執行整體時的第一步。比如說剛開始我們可以讓進度對話框顯示。還可以做一些初始化的邏輯操作。

@Override
	protected XX doInBackground(String... params)
	{
super.doInBackground(String... params);
        return XX類型 ;
}
           

                第二部:首先XX代表需要傳回結果的類型 比如說 Integer,String,bitmap等  這個方法的作用是 做一些比較耗時的邏輯操作。 也就是說 主體需要做的事情。 最常見的如 網絡請求。                  在這個方法中  我們會調用 publishProgress(Integer.. values)來重新整理進度條 這樣就會執行下面的這個方法:               

@Override
	protected void onProgressUpdate(Integer... values)
	{
	    // TODO Auto-generated method stub
	    Log.i("TAG", "2");
	    super.onProgressUpdate(values);
	    dialog.setProgress(values[0]);
	}
           

                   第三部,就是在第二部調用了 publishProgress(Integer .. values)  然後執行這個方法進行 UI的更新。 最常用的 進度條對話框 百分比更新。                                 

protected void onPostExecute(Bitmap result)
	{
 
	    super.onPostExecute(result);
	    dialog.dismiss();
	    image.setImageBitmap(result);
	}
           

                              第四部就是 執行完了 邏輯操作。最後要做什麼事情。氣勢可以把這個了解成 異常中的finaly 最後會執行這一塊。 比如說 網絡請求網絡,最後要把這個擷取到 的圖檔包裝成Bitmap 然後作為結果傳回來,最後Imageview設定這個圖檔。

                   介紹完了方法的使用,接下來我們來實戰:                (網絡請求一張圖檔)

                    首先在XML朱布局檔案中放置一個Imageview  以及Button  。然後在JAVA代碼中初始化

                    建立一個類繼承于 AsyncTask<String, Integer, Bitmap> 代碼如下:                                      

class myTask extends AsyncTask<String, Integer, Bitmap>
    {
    }
           

               String:要請求的URL                Integer:可以了解成進度條的刻度                Bitmap:最後傳回的結果

          在按鈕點選的監聽的事件中       new myTask().execute(path); 執行異步操作。             參數Path: 要請求的URL位址  也就是圖檔的位址。

// 第一步要執行的
	@Override
	protected void onPreExecute()
	{
	    Log.i("TAG", "1");
	    super.onPreExecute();
	    dialog.show();

	}
           
// 需要執行的耗時工作
	@Override
	protected Bitmap doInBackground(String... params)
	{

	    Log.i("TAG", "3");
	    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
	    InputStream inputStream = null;
	    Bitmap bitmap = null;

	    try
	    {
		HttpClient httpClient = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(params[0]);
		HttpResponse httpResponse = httpClient.execute(httpGet);
		if (httpResponse.getStatusLine().getStatusCode() == 200)
		{
		    Log.i("TAG", "TEST IF");
		    // 擷取輸入流
		    inputStream = httpResponse.getEntity().getContent();
		    // 現貨的檔案的總長度
		    long file_length = httpResponse.getEntity().getContentLength();
		    // 一次擷取的長度mjku
		    int len = 0;
		    // 位元組數組
		    byte[] data = new byte[1024];
		    int totle_length = 0;
		    while ((len = inputStream.read(data)) != -1)
		    {
			Log.i("TAG", "TEST");
			totle_length += len;
			int value = (int) ((totle_length / (float) file_length) * 100);
			publishProgress(value);
			byteArrayOutputStream.write(data, 0, len);
		    }
		    byte[] result = byteArrayOutputStream.toByteArray();
		    bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
		}

	    } catch (ClientProtocolException e)
	    {
		// TODO Auto-generated catch block
		e.printStackTrace();
		Log.i("TAG", e.toString());
	    } catch (IOException e)
	    {
		// TODO Auto-generated catch block
		e.printStackTrace();
		Log.i("TAG", e.toString());
	    } finally
	    {
		if (inputStream != null)
		{
		    try
		    {
			inputStream.close();
		    } catch (IOException e)
		    {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    }
		}
	    }

	    return bitmap;
	}
           

                網絡請求這裡要導入網絡請求的相應JAR包。                 int value 這一步計算刻度                    (int((累計長度長度/(float)檔案的總長度)*100%)                                 

// UI進度條更新
        @Override
	protected void onProgressUpdate(Integer... values)
	{
	    // TODO Auto-generated method stub
	    Log.i("TAG", "2");
	    super.onProgressUpdate(values);
	    dialog.setProgress(values[0]);
	}
           
// 在執行完畢之後 要做的事情
	@Override
	protected void onPostExecute(Bitmap result)
	{
	    Log.i("TAG", "4");
	    super.onPostExecute(result);
	    dialog.dismiss();
	    image.setImageBitmap(result);
	}
           

                      最後的運作結果:              

Android多線程程式設計AsyncTask                                        Android多線程程式設計AsyncTask
Android多線程程式設計AsyncTask                                        Android多線程程式設計AsyncTask