Android必學——AsyncTask

第一章  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。
相關文章
相關標籤/搜索