国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用AsyncTask進行異步加載

2019-11-08 00:06:08
字體:
來源:轉載
供稿:網友

對于異步加載在平常的開發中使用的最多的就是Thread+Handler來完成的,但在處理單個后臺異步任務的時候使用Handler進行處理會顯得代碼比較多,而且結構比較復雜,當然這是相對于AsyncTask來講的,但是在進行多個異步操作以及也涉及到UI的更新操作的時候使用AsyncTask就會變得復雜起來,對于異步加載方案的選擇還是需要以及業務邏輯的復雜程度來決定。

為了進行更簡單的異步操作,Google為我們提供了AsyncTask進行異步操作,當然底層也是Thread和Handler的封裝。

下面看一下使用AsyncTask進行異步加載的步驟:

1.繼承AsyncTask抽象類,實現下面的方法:

class MyAsyncTask extends AsyncTask<Void,Void,Void>{ @Override PRotected void onPreExecute() { super.onPreExecute(); } @Override protected Void doInBackground() { } @Override protected void onProgressUpdate() { super.onProgressUpdate(values); } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); } }

在繼承AsyncTask的時候需要傳入三個泛型參數:

a: Params: 在執行AsyncTask時需要的參數,用于在后臺任務中使用,作為doInBackground( )方法的參數傳遞進去

b: Progress: 后臺任務執行的時候,如果需要在界面上顯示進度,此處的反省執行的類型,為進度的單位,一般為Integer

c: Result: 當后臺任務執行完畢后需要返回值的的類型

注: 如果不需要傳遞參數,或者不需要返回值,此處將泛型指定為Void即可

AsyncTask抽象類幾個常用方法的介紹:

a: onPreExecute(): 此方法在后臺任務開始之前調用,用于進行界面上的初始化操作,比如顯示一個進度條的對話框

b: doInBackground(): 此方法中的代碼在子線程執行,一般用于處理一些耗時操作。doInBackground中的參數在AsyncTask的實例調用execute( )方法的時候傳入,當然傳入參數的類型與Params的類型有關,如果Params的泛型設置為Void則不需要傳遞參數。還有一點需要注意的是,由于此方法是執行在子線程中的,因此不能在該方法中進行更新Ui的操作。

c: onProgressUpdate(): 在 doInBackground()方法中調用了 publishProgress()方法后,此方法將很快被調用,在這個方法 中可以進行更新UI的操作,根據 publishProgress()傳入的參數進行Ui進度的更新。

d: onPostExecute(): 當doInBackground中的任務執行完畢并通過return 返回后,就會調用此方法,doInBackground()方法返回的數據會作為參數傳遞到onPostExecute()方法中,此時可以利用返回的結果進行Ui的操作,或者關閉對話框。

一個最簡單的異步任務只需要實現 doInBackground() 和onPostExecute()即可。


2.創建AsyncTask實例,執行任務:

MyAsyncTask myAsyncTask = new MyAsyncTask(); myAsyncTask.execute();

當然這里的execute()方法需要傳遞參數的類型,是由Params的泛型決定,如果為Void則不需要傳遞參數。 需要注意的是,一個AsyncTask的實例,只能執行一次execute()方法,如果執行多次會出現下面的異常:

這里寫圖片描述

execute()方法的實現:

//定義的關于任務運行狀態的幾個枚舉類型 public static enum Status { FINISHED, PENDING, RUNNING; private Status() { } } public final AsyncTask<Params, Progress, Result> execute(Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: //如果該任務處在運行狀態則拋出異常 throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: //如果該任務已經執行完成則拋出異常 throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; sExecutor.execute(mFuture); return this; }

通過查看源碼之后也就明白了為什么一個實例的execute()只能執行一次。


下面通過一個從網絡加載圖片的例子來使用一下AsyncTask:

運行效果:

這里寫圖片描述

示例代碼:

/** * 使用AsyncTask進行網絡圖片加載并顯示到ImageView */public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener { private ImageView imageView; private EditText editText; private Button btnSubmit; private String mImageUrl; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ansy_task); InitUI(); btnSubmit.setOnClickListener(this); } private void InitUI() { imageView = (ImageView) findViewById(R.id.imageView_net); editText = (EditText) findViewById(R.id.edt_img_url); btnSubmit = (Button) findViewById(R.id.btn_show); } @Override public void onClick(View view) { MyAsyncTask myAsyncTask = new MyAsyncTask(); mImageUrl = editText.getText().toString(); myAsyncTask.execute(mImageUrl); } /** * 繼承 AsyncTask 抽象類三個泛型參數的作用 * 1.Params: 在執行AsyncTask時需要的參數,用于在后臺任務中使用 (doInBackground) * 2.Progress: 后臺任務執行的時候,如果需要在界面上顯示進度,此處的反省執行的類型,為進度的單位,一般為Integer * 3.Result: 當后臺任務執行完畢后需要返回值的的類型 * 如果不需要傳遞參數,或者不需要返回值,此處將泛型指定為Void即可 */ class MyAsyncTask extends AsyncTask<String,Integer,Bitmap>{ /** * 此方法在后臺任務開始之前調用,用于進行界面上的初始化操作,比如顯示一個進度條的對話框 */ @Override protected void onPreExecute() { super.onPreExecute(); Log.i("wk","onPreExecute()方法執行了,此方法用于進行初始化相關的工作"); } /** *此方法中的代碼執行在子線程,用于處理一些耗時操作, * doInBackground(String... strings)中的參數在 execute(str)方法中傳入。 * 處理完后使用return返回處理結果 * * 當需要反饋當前操作進度的時候,可以調用publishProgress()方法來完成,根據傳遞的參數,在onProgressUpdate() * 進行顯示進度的狀態。 * * 注:由于代碼運行在子線程,不能在這個方法中進行更新UI的操作。 * * String ...屬于不定參數,可以傳遞對個String對象 * @param strings * @return */ @Override protected Bitmap doInBackground(String... strings) { Log.i("wk","imageUrl:"+strings[0]); //調用此方法來觸發 onProgressUpdate()方法的執行,傳入參數進行進度的更新 publishProgress(100); InputStream is = getStreamFromUrl(strings[0]); Bitmap bitmap = BitmapFactory.decodeStream(is); return bitmap; } /** * 在 doInBackground()方法中調用了 publishProgress()方法后,此方法將很快被調用,在這個方法 * 中可以進行更新UI的操作,根據 publishProgress();傳入的參數進行進度的更新 * @param values */ @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); Log.i("wk","當前進度:"+values[0]); } /** * 當后臺任務執行完畢并通過return 返回后,就會調用此方法,doInBackground()方法返回的 * 數據會作為參數傳遞到onPostExecute()方法,此時可以利用返回的結果進行Ui的操作,或者關閉對話框。 * @param bitmap */ @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); imageView.setImageBitmap(bitmap); } } /** * * 根據Image的URL獲取流 * @param string * @return */ private InputStream getStreamFromUrl(String string) { try { URL url = new URL(string); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setDoInput(true); InputStream inputStream = conn.getInputStream(); if(inputStream!=null){ return inputStream; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { } return null; }}

^_^


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 友谊县| 永昌县| 礼泉县| 大化| 秀山| 江门市| 庄河市| 龙里县| 定远县| 济源市| 龙山县| 阿克苏市| 白银市| 滦平县| 华阴市| 寿阳县| 皮山县| 廉江市| 奎屯市| 南和县| 濮阳市| 库伦旗| 郴州市| 贵阳市| 泽州县| 紫云| 娱乐| 汾西县| 乌审旗| 景东| 梅州市| 务川| 鲁山县| 太仓市| 娱乐| 彰武县| 韶关市| 贞丰县| 响水县| 简阳市| 绿春县|