第一章 AsyncTask的基本構成java
爲是麼要異步任務android
1)Android單線程模型網絡
2)耗時操做放在非主線程中執行異步
AsyncTask爲什麼而生async
1)子線程中跟新UIide
2)封裝、簡化異步操做post
public class MyAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) {//必須重寫,其餘方法沒有規定必須重寫 // TODO 自動生成的方法存根 Log.d("TAG", "doInBackground"); publishProgress();//輸入的參數會在onProgressUpdate()方法中獲取到 return null; } @Override protected void onPreExecute() { // TODO 自動生成的方法存根 super.onPreExecute(); Log.d("TAG", "onPreExecute"); } @Override protected void onPostExecute(Void result) { // TODO 自動生成的方法存根 super.onPostExecute(result); Log.d("TAG", "onPostExecute"); } @Override protected void onProgressUpdate(Void... values) { super.onProgressUpdate(values); Log.d("TAG", "onProgressUpdate"); } } //另類 MyAsyncTask task=new MyAsyncTask(); task.execute();//相似線程中的start()方法 Ps:順序:onPreExecute()->doInBackground(Params...)->調用publishProgress(Progress...)->onProgressUpdate(Progress...)->doInBackground(Params...)執行結束->onPostExecute(Result)
第二章 AsyncTask的使用示例url
網絡操做做爲不穩定的廢時操做,從android 4.0開始就被嚴禁放入主線程中 一般採用在異步線程處理下載圖像 在UI線程設置圖像 ProgressBar XML屬性 visibility="gone"可設置爲默認狀態下爲隱藏 VISIBLE:設置控件可見 INVISIBLE:設置控件不可見 GONE:設置控件隱藏 而INVISIBLE和GONE的主要區別是:當控件visibility屬性爲INVISIBLE時,界面保留了view控件所佔有的空間;而控件屬性爲GONE時,界面則不保留view控件所佔有的空間。
URLConnection connection //定義網絡對象<br> ImputString is//定義用於獲取數據的輸入流<br> connection=new URL(url).openConnection();//獲取網絡鏈接對象<br> is= connection.getInputStream();//得到輸入流<br> BufferedInputStream bis=new BufferedInputStream(is);//封裝輸入流<br> bitmap=BitmapFactory.decodeStram(bis);將輸入流解析成bitmap<br> is.close();<br> bis.close();//關閉輸入流<br> 1.獲取傳遞進來的參數值<br> string url=params[0];<br> 2.訪問網的操做<br> 創建鏈接--設置輸入流--封裝輸入流--decode輸出流,轉化爲所須要的文件--關閉輸入流和封裝流 最後將所須要的文件返回
上述方法是寫在doInBackground()裏面的。spa
經過OnProExcute方法和onPostExcute方法操做UI設置圖像 mProgressBar.setVisbility(View.VISIBLE)顯示進度條 onPostExcute(BitMap bitmap)//bitmap爲doingbackground方法返回的一個bitmap 在Main方法中,調用MyAsycTask的execute方法傳入(URL) 經過AsyncTask的實例調用execute方法就能夠開啓AsyncTask的異步操做,在execute方法中傳入一個或多個參數做爲咱們doingbackground方法中所傳進來的一個參數 在AsyncTask的OnPreExecute方法中調用初始化的方法,在後臺啓動異步操做提示用戶等待,調用真正的doingBackGround方法開始真正的異步處理,這裏的整個方法都是如今子線程之中,在這個方法中進行全部的耗時操做,並將所要返回的值返回到咱們所設定的值的類型中,在OnpostExecute方法中得到咱們所返回的結果,onPostExcute方法也運行在主線程之中從而咱們能夠對UI進行操做,這就是AsyncTask所要調用的整個流程 在Mainfest中開通所要訪問的網絡權限
onPreExecute() 顯示進度條 onPostExcute()隱藏進度條 均可以訪問UI線程 mytask.execute(args)中傳入的參數就是doInBackground中的參數 onPreExecute--加載進度條 doInBackGround--下載網絡數據(耗時操做) onPostExecute--顯示圖片 與UI線程通訊 在onPreExecute()方法中 mProgressBar.setVisibility(View.VISIBLE);//顯示進度條 在onPostExectute(Bitmap bitmap)方法中,參數是doInBackground()方法返回的參數 mProgressBar.setVisibility(View.GONE);//將進度條隱藏 mImageView.setImageBitmap(bitmap);//將圖片設置爲解析出來的網絡圖片 而後在onCreate方法中 new MyAsyncTask().execute(URL);//開啓AsyncTask的異步線程操做,設置傳遞進去的參數
第三章 AsyncTask模擬進度條線程
在AsyncTask的doInBackground()方法中調用publishProgress()方法能夠將咱們處理任務的進度反饋處理,
咱們這個時候就是用AsyncTask的onProgressUpdate()方法來承接咱們傳出來的進度,注意,因爲在AsyncTask中,
只有doInBackground()方法是工做在子線程中的,因此咱們能夠放心地在onProgressUpdate()方法中更新UI
for(int i=0;i<100;i++){ publishProgress(i); try{ Thread.sleep(300); } catch(InterruptedException e){ e.printStackTrace(); } } onProgressUpdate(Integer...values){ super.onProgressUpdate(values); //獲取進度更新值 mProgressBar.setProgress(values[0]); }
AsyncTask默認狀況下會等待前一個線程執行完畢後再執行下一個線程,要取消該機制,可讓AsyncTask和Activity的生命週期保持一致 protected void onPause(){ super.onPause(); if(mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING){ //只是發送了一個取消請求,將AsyncTask標記爲cancel狀態,但未真正取消線程的執行 //實際上JAVA語言沒辦法粗暴地直接中止一個正在運行的線程 mTask.cancel(true); } } 因此須要在doInBackground方法和onProgressUpdate方法中增長isCancelled()方法進行判斷,標記爲cancel的,則跳出循環,儘快結束當前線程的剩餘操做,開始下一個線程 AsyncTask實現的機制:底層經過線程池來做用的,當咱們一個線程沒有執行完畢時,後面的線程是沒法執行的; 調用cancel方法去cancel一個asynctask線程,並無將這個線程直接中止掉,只是給這個asynctask發送了一個cancel請求,將它標識爲cancel狀態; 在java中是沒法直接將一個線程粗暴地中止掉,咱們必須等一個線程執行完畢後才能作後面的操做。(需經過狀態值判斷去跳出子線程的循環操做) 只有doInBackground是在非UI線程中執行 mytask!=null&&mytask.getStatus()== AsyncTask.Status.RUNNING ansystask 即便cancel設置爲true 也不能當即取消,只是將狀態設爲取消 故在doInBackground和onUpdatexx的時候檢測isCancled()是否是true
doInBackground()方法運行在非主線程,其餘三個方法運行在主線程,因此能夠在doInBackground作異步操做,在其餘三個方法中更新UI。 正是由於有了onProgressUpdate()和onPostExcute()方法,才能夠在異步處理的過程當中更新UI。