Android日記之AsyncTask的基本使用

前言

第一次寫文章围段,記錄下自己新手Android路上的開發(fā)點(diǎn)滴,之前學(xué)過AsyncTask基本使用芋忿,記錄一下炸客,要不然老是忘記。如有發(fā)現(xiàn)不對(duì)的地方也請(qǐng)多多指教戈钢。

正文

AsyncTask是什么嚷量?

AsyncTask就是異步處理的任務(wù),它是Handler加上線程池的封裝類逆趣,線程池可以維護(hù)數(shù)量,主要是可以避免不必要的創(chuàng)建和開銷嗜历,AsyncTask必須要在實(shí)例的主線程中創(chuàng)建宣渗,它的回調(diào)方法,Android也會(huì)自動(dòng)的去調(diào)用梨州,注意的是痕囱,一個(gè)AsyncTask的實(shí)例,只能調(diào)用一次的excute方法暴匠。

AsyncTask的基本使用

首先AsyncTask是一個(gè)抽象類鞍恢,用于被繼承,而且要指定3個(gè)泛型參數(shù)每窖,也可以3個(gè)都指定為空帮掉。

public class MyAsyncTask extends AsyncTask<Params,Progress,Result> {

    @Override
    protected Void doInBackground(Void... voids) {
        return null;
    }
}
//Parm:啟動(dòng)任務(wù)時(shí)輸入?yún)?shù)的類型
//Progress:后臺(tái)任務(wù)執(zhí)行中返回的進(jìn)度值
//Result:后臺(tái)執(zhí)行完成后返回結(jié)果的類型

構(gòu)建 AsyncTaskd子類的回調(diào)方法。

  • doInBackground():必須重寫窒典,異步執(zhí)行后臺(tái)線程將要完成的任務(wù)蟆炊。
  • onPreExecute():執(zhí)行后臺(tái)耗時(shí)操作前被調(diào)用,一般用來完成用戶一些初始化操作瀑志。
  • onPostExecute():當(dāng)doInBackground方法完成后涩搓,系統(tǒng)會(huì)自動(dòng)調(diào)用,并且會(huì)將doInBackground返回的值傳遞給該方法劈猪。
  • onProgressUpdate():在doInBackground方法調(diào)用publishProgress方法后昧甘,更新任務(wù)的執(zhí)行進(jìn)度后,就會(huì)觸發(fā)該方法战得。

代碼如下:

package com.ju.synctask;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import java.io.InputStream;
import java.net.URLConnection;

/**
 * 項(xiàng)目名: SyncTask
 * 包名 com.ju.synctask
 * 文件名: ImageTest
 * 創(chuàng)建日期:2019/4/1
 * 描述:圖片加載測(cè)試類
 */
public class ImageTest extends AppCompatActivity {

    private static final String URL = "https://bmob-cdn-23214.b0.upaiyun.com/2019/03/30/9b72512c409fc6bd806acb50a7e7c748.jpg";
    private ImageView iv;
    private ProgressBar bar;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.image);

        iv = findViewById(R.id.iv);
        bar = findViewById(R.id.pro);

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


    private class MyAsyncTask extends AsyncTask<String, Void, Bitmap> {


        @Override
        protected Bitmap doInBackground(String... strings) {
            //取出相應(yīng)的參數(shù)值

            String url = strings[0];
            Bitmap bitmap = null;
            URLConnection connection;
            InputStream is;
            try {
                connection = new URL(url).openConnection();
                is = connection.getInputStream();//獲取輸入流
                BufferedInputStream bis = new BufferedInputStream(is);
                bitmap = BitmapFactory.decodeStream(bis);//將輸入流解析成bitmap
                bis.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return bitmap;
        }


        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //初始化
            bar.setVisibility(View.VISIBLE);

        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            //獲取doInBackground的返回值充边,最后進(jìn)行處理
            iv.setImageBitmap(bitmap);
            bar.setVisibility(View.GONE);
        }
    }

}

圖片加載測(cè)試結(jié)果.png

模擬進(jìn)度條測(cè)試

package com.ju.synctask;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ProgressBar;

public class PBActivity extends AppCompatActivity {


    private ProgressBar bar;
    PAsyncTask pAsyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pbactiviity);
        bar = findViewById(R.id.progress);
        pAsyncTask = new PAsyncTask();
        pAsyncTask.execute();

    }



    private class PAsyncTask extends AsyncTask<Void, Integer, Void> {

        @Override
        protected Void doInBackground(Void... voids) {
            
            //通過for循環(huán)模擬進(jìn)度條進(jìn)度
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                publishProgress(i);
            }
            return null;
        }


        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            bar.setProgress(values[0]);
        }
    }
}

進(jìn)度條測(cè)試結(jié)果

但是你這樣做發(fā)現(xiàn)了一個(gè)問題,如果點(diǎn)擊返回的話然后再次進(jìn)入會(huì)發(fā)現(xiàn)進(jìn)度條不動(dòng)了贡避,這其實(shí)是因?yàn)樯弦淮蔚倪M(jìn)度條任務(wù)沒有完成痛黎,AsyncTask的任務(wù)要進(jìn)行排隊(duì),那要怎么解決了刮吧,很簡單湖饱,可以讓AsyncTask和Activity的生命周期保持一次。

在Activity的聲明周期添加上這個(gè)

   @Override
    protected void onPause() {
        super.onPause();
        if (pAsyncTask != null && pAsyncTask.getStatus() == AsyncTask.Status.RUNNING) {
            pAsyncTask.cancel(true);
        }
    }

再一次跑起來杀捻,發(fā)現(xiàn)沒什么卵用啊井厌。其實(shí),我們通過調(diào)用cancel調(diào)用的時(shí)候,并沒有吧AsyncTask的線程給停止掉仅仆,我們只是給這個(gè)AsyncTask發(fā)送了一個(gè)cancel的請(qǐng)求器赞,標(biāo)記為cancel的狀態(tài)而已。并不是真正的取消線程執(zhí)行墓拜。我們需要在doInBackground()onProgressUpdate()添加一個(gè)isCancelled()判斷港柜,來進(jìn)行停止AsyncTask,這樣就可以停止掉了咳榜。

@Override
protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);
    if (isCancelled()) {
        return;
    }
    bar.setProgress(values[0]);
}

總結(jié)

AsyncTask的基本使用方法就到此為止了夏醉,需要注意的一點(diǎn)是AsyncTask必須要在UI線程也就是主線程中進(jìn)行創(chuàng)建,也必須在UI線程中調(diào)用excute方法涌韩,重寫的那四個(gè)方法是自動(dòng)調(diào)用的畔柔。每個(gè)AsyncTask只能被執(zhí)行一次,多次調(diào)用有可能會(huì)出現(xiàn)異常臣樱。也不能在doInBackground()方法里面更新UI靶擦,一定要在onProgressUpdate里進(jìn)行更新才行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末雇毫,一起剝皮案震驚了整個(gè)濱河市玄捕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌棚放,老刑警劉巖桩盲,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異席吴,居然都是意外死亡赌结,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門孝冒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來柬姚,“玉大人,你說我怎么就攤上這事庄涡×砍校” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵穴店,是天一觀的道長撕捍。 經(jīng)常有香客問我,道長泣洞,這世上最難降的妖魔是什么忧风? 我笑而不...
    開封第一講書人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮球凰,結(jié)果婚禮上狮腿,老公的妹妹穿的比我還像新娘腿宰。我一直安慰自己,他們只是感情好缘厢,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開白布吃度。 她就那樣靜靜地躺著,像睡著了一般贴硫。 火紅的嫁衣襯著肌膚如雪椿每。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,837評(píng)論 1 290
  • 那天英遭,我揣著相機(jī)與錄音拖刃,去河邊找鬼。 笑死贪绘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的央碟。 我是一名探鬼主播税灌,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼亿虽!你這毒婦竟也來了菱涤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬榮一對(duì)情侶失蹤洛勉,失蹤者是張志新(化名)和其女友劉穎粘秆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體收毫,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡攻走,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了此再。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昔搂。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖输拇,靈堂內(nèi)的尸體忽然破棺而出摘符,到底是詐尸還是另有隱情,我是刑警寧澤策吠,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布逛裤,位于F島的核電站,受9級(jí)特大地震影響猴抹,放射性物質(zhì)發(fā)生泄漏带族。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一蟀给、第九天 我趴在偏房一處隱蔽的房頂上張望炉菲。 院中可真熱鬧堕战,春花似錦、人聲如沸拍霜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽祠饺。三九已至越驻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間道偷,已是汗流浹背缀旁。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留勺鸦,地道東北人并巍。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像换途,于是被迫代替她去往敵國和親懊渡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • 在Android中我們可以通過Thread+Handler實(shí)現(xiàn)多線程通信军拟,一種經(jīng)典的使用場(chǎng)景是:在新線程中進(jìn)行耗時(shí)...
    呂侯爺閱讀 2,041評(píng)論 2 23
  • 由于Android的特性剃执,如果要執(zhí)行耗時(shí)操作,則必須方法子線程中執(zhí)行懈息。除了Thread可以開啟子線程外肾档,Andro...
    Ruheng閱讀 25,730評(píng)論 6 18
  • 參考 https://www.baidu.com/link?url=QNRznJEBT25k0bpgVD3bOni...
    CodeInfo閱讀 381評(píng)論 0 0
  • Android開發(fā)者:你真的會(huì)用AsyncTask嗎怒见? 導(dǎo)讀.1 在Android應(yīng)用開發(fā)中,我們需要時(shí)刻注意保證...
    cxm11閱讀 2,703評(píng)論 0 29
  • 念先生好姑宽,父母年事已高速种,喜歡吃稀飯,在超市采購各種煮稀飯的食材低千,給父母煮稀飯配阵。把水果用料理機(jī)機(jī)碎,這樣父母吃水果也...
    于宏偉1472閱讀 95評(píng)論 0 0