第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開(kāi)發(fā)者教程

Android 入門(mén)教程

菜單類(lèi)控件
菜單:Menu
并發(fā)編程
多線(xiàn)程

AsyncTask:異步任務(wù)

在前面的章節(jié)有提到過(guò),Android 系統(tǒng)默認(rèn)會(huì)在主線(xiàn)程(UI 線(xiàn)程)執(zhí)行任務(wù),但是如果有耗時(shí)程序就會(huì)阻塞 UI 線(xiàn)程,導(dǎo)致頁(yè)面卡頓。這時(shí)候我們通常會(huì)將耗時(shí)任務(wù)放在獨(dú)立的線(xiàn)程,然后通過(guò) Handler 等線(xiàn)程間通信機(jī)制完成 UI 的刷新。很多時(shí)候我們也許只是想執(zhí)行一個(gè)簡(jiǎn)單的任務(wù),為此寫(xiě)一套 Handler 線(xiàn)程通信就會(huì)顯得比較復(fù)雜,不用擔(dān)心,Android 系統(tǒng)為我們提供了一個(gè)專(zhuān)門(mén)用于執(zhí)行異步任務(wù)的工具——Async Task,它可以讓我們執(zhí)行后臺(tái)任務(wù)并輕松的與 UI 線(xiàn)程進(jìn)行狀態(tài)同步,今天就一起來(lái)學(xué)習(xí)一下 AyncTask 的用法。

1. AsyncTask 簡(jiǎn)介

AsyncTask 類(lèi)通常用來(lái)在執(zhí)行后臺(tái)任務(wù)的同時(shí)刷新 UI,通過(guò)調(diào)用execute()方法觸發(fā)后臺(tái)任務(wù)的執(zhí)行,首先會(huì)回調(diào) AsyncTask 的onPreExecute(),接著回調(diào)doInBackground()來(lái)執(zhí)行自定義的后臺(tái)任務(wù),最后回調(diào)onPostExecute()方法用來(lái)刷新 UI,整體流程示意圖如下:

圖片描述

2. AsyncTask 的基本用法

2.1 聲明 AsyncTask

我們不能直接創(chuàng)建 AsyncTask,正確的方法是繼承自 AsyncTask 實(shí)現(xiàn)一個(gè)它的子類(lèi),如下:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
        protected Long doInBackground(URL... urls) {
             // 執(zhí)行后臺(tái)耗時(shí)任務(wù)
            return;
        }

        protected void onProgressUpdate(Integer... progress) {
            // 任務(wù)執(zhí)行進(jìn)度更新
        }

        protected void onPostExecute(Long result) {
            // 執(zhí)行完畢,更新UI
        }
    }

以上是 AsyncTask 的核心回調(diào)方法,每個(gè)方法的含義會(huì)在后面具體講到。

2.2 指定參數(shù)

AsyncTask 可以幫助你在子線(xiàn)程和主線(xiàn)程之間同步參數(shù),根據(jù)不同的業(yè)務(wù)場(chǎng)景,參數(shù)類(lèi)型和個(gè)數(shù)也會(huì)不一樣。剛剛在 2.1 小節(jié)聲明 AyncTask 子類(lèi)的時(shí)候,需要傳入 3 個(gè)泛型參數(shù):

  • TypeOfVarArgParams:
    在任務(wù)啟動(dòng)之后,傳入給后臺(tái)任務(wù)的參數(shù)類(lèi)型

  • ProgressValue:
    啟動(dòng)之后到任務(wù)結(jié)束之間,系統(tǒng)會(huì)不斷回調(diào)此方法,用來(lái)更新任務(wù)的進(jìn)度

  • ** ResultValue:**
    后臺(tái)任務(wù)的執(zhí)行結(jié)果

2.3 啟動(dòng)后臺(tái)任務(wù)

在聲明完后臺(tái)任務(wù)之后,就可以直接啟動(dòng)了。啟動(dòng)方式比較簡(jiǎn)單,直接通過(guò)調(diào)用execute()方法啟動(dòng)后臺(tái)任務(wù):

new DownloadFilesTask().execute(url1, url2, url3);

3 AsyncTask 關(guān)鍵回調(diào)方法

AsyncTask 是由 4 個(gè)回調(diào)方法配合組成,這 4 個(gè)回調(diào)方法按照一定的順序依次被調(diào)用,所以我們需要 focus 的是在正確的回調(diào)方法中實(shí)現(xiàn)我們想要的邏輯,下面詳細(xì)看看如何使用。

  • onPreExecute():
    在執(zhí)行execute()方法之后該方法立即被調(diào)用,標(biāo)志著 AyncTask 正式開(kāi)啟。通常用來(lái)做一些需要在后臺(tái)任務(wù)開(kāi)啟之前完成的初始化工作,比如展示一個(gè)進(jìn)度條、或者彈出一個(gè)對(duì)話(huà)框等等。該方法在 UI 線(xiàn)程執(zhí)行。
  • doInBackground(Params):
    在執(zhí)行完onPreExecute()方法之后立即被調(diào)用,用來(lái)執(zhí)行需要放在后臺(tái)執(zhí)行的耗時(shí)任務(wù)。在創(chuàng)建 AsyncTask 的時(shí)候傳入的參數(shù)就是提供給doInBackground使用的。在后臺(tái)任務(wù)執(zhí)行完畢后,還需要將執(zhí)行結(jié)果返回到onPostExecutes ()中,同時(shí)我們也可以通過(guò)publishProgress(Progress…)方法來(lái)手動(dòng)發(fā)布任務(wù)進(jìn)度,進(jìn)度將從子線(xiàn)程發(fā)送到 UI 線(xiàn)程。毋庸置疑,該方法在子線(xiàn)程中執(zhí)行。
  • onProgressUpdate(Progress…):
    當(dāng)我們通過(guò)publishProgress(Params)發(fā)布進(jìn)度之后,系統(tǒng)會(huì)回調(diào)該方法,用來(lái)獲取任務(wù)執(zhí)行進(jìn)度并更新 UI。這一步就完成了子線(xiàn)程到主線(xiàn)程的通信,該方法在 UI 線(xiàn)程執(zhí)行
  • onPostExecute(Result):
    當(dāng)后臺(tái)任務(wù)執(zhí)行完畢,該方法被回調(diào),同時(shí)標(biāo)志著整個(gè) AyncTask 結(jié)束。與onPreExecute相反,通常會(huì)在onPostExecute中做一些回收工作,比如提示“下載完成”、“加載失敗”、隱藏進(jìn)度條等等。

4 AsyncTask 示例

本節(jié)的功能和第 38 節(jié) Handler 的功能類(lèi)似,我們還是完成一個(gè)后臺(tái)執(zhí)行耗時(shí)任務(wù),并同步更新進(jìn)度條的功能,可以直接在 Handler 的例子上修改。

4.1 布局文件

布局文件基本一樣,只是默認(rèn)將進(jìn)度條和進(jìn)度顯示隱藏起來(lái),等到onPreExecute()方法的時(shí)候在做初始化展示,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ProgressBar
        android:visibility="gone"
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true" />

    <Button
        android:id="@+id/start_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/progressBar"
        android:layout_alignParentStart="true"
        android:layout_marginStart="24dp"
        android:layout_marginTop="62dp"
        android:text="開(kāi)始任務(wù)" />

    <TextView
        android:visibility="gone"
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/start_progress"
        android:layout_alignBottom="@+id/start_progress"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="85dp"
        android:gravity="center"
        android:text="當(dāng)前進(jìn)度:0%"
        android:textSize="16sp" />

</RelativeLayout>

4.2 異步任務(wù)控制

異步任務(wù)的代碼基本上和 Handler 一致,我們通過(guò)Thread.sleep(1000)來(lái)模擬一秒鐘的耗時(shí)操作,然后在onPreExecute()中展示進(jìn)度條,在后臺(tái)任務(wù)執(zhí)行完后通過(guò)publishProgress(int)來(lái)將任務(wù)進(jìn)度發(fā)送到主線(xiàn)程,由onProgressUpdate(int)方法在 UI 線(xiàn)程接收進(jìn)度,并更新進(jìn)度條。最后在結(jié)束的時(shí)候返回“已完成”提示,在onPostExecute(String)方法中進(jìn)行收尾工作,隱藏進(jìn)度條并展示“已完成”。代碼如下:

package com.emercy.myapplication;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity {

    private static final int MAX = 100;

    private ProgressBar progressBar;
    private Button startProgress;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar = findViewById(R.id.progressBar);
        startProgress = findViewById(R.id.start_progress);
        textView = findViewById(R.id.textView);
        progressBar.setMax(MAX);

        startProgress.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new DownloadTask().execute();
            }
        });
    }

    // 1、創(chuàng)建Async Task子類(lèi)
    private class DownloadTask extends AsyncTask<Integer, Integer, String> {

        // 2、初始化階段,展示進(jìn)度條
        @Override
        protected void onPreExecute() {
            progressBar.setVisibility(View.VISIBLE);
            textView.setVisibility(View.VISIBLE);
        }

        // 3、執(zhí)行后臺(tái)任務(wù)
        @Override
        protected String doInBackground(Integer... integers) {
            int i;
            for (i = 0; i < 100; i++) {
                try {
                    // 一秒鐘的耗時(shí)操作
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 4、發(fā)布進(jìn)度
                publishProgress(i);
            }
            return "異步任務(wù)已完成";
        }

        // 5、接收后臺(tái)任務(wù)數(shù)據(jù)并更新進(jìn)度條
        @Override
        protected void onProgressUpdate(Integer... values) {
            textView.setText("當(dāng)前進(jìn)度:" + values[0] + "%");
            progressBar.setProgress(values[0]);
        }

        // 6、任務(wù)結(jié)束
        @Override
        protected void onPostExecute(String s) {
            progressBar.setVisibility(View.GONE);
            textView.setText(s);
        }
    }
}

編譯之后,效果如下:

圖片描述

可以看到大體的效果和 Handler 是一樣的,但是整個(gè)異步任務(wù)的處理流程更加清晰了,而且可以很方便的做任務(wù)前的初始化任務(wù)后的回收工作,整個(gè)線(xiàn)程的切換也不再需要我們?nèi)タ刂疲拷唤o AsyncTask 操作就行,一切就是這么簡(jiǎn)單!

5 小結(jié)

本節(jié)介紹了一個(gè)專(zhuān)門(mén)用于執(zhí)行異步任務(wù)的工具類(lèi),首先需要?jiǎng)?chuàng)建一個(gè)子類(lèi)繼承自 AsyncTask,然后確定好需要傳入和返回的參數(shù)類(lèi)型,接著覆寫(xiě) 4 個(gè)關(guān)鍵的方法,剩下的線(xiàn)程切換及數(shù)據(jù)傳輸就交給系統(tǒng)完成了。
相比 Handler,AsyncTask使用更簡(jiǎn)單,我們只需要關(guān)注我們的后臺(tái)邏輯,而 Handler 需要我們自行管理的東西比較多。所以在執(zhí)行后臺(tái)任務(wù)刷新 UI 的場(chǎng)景,強(qiáng)烈推薦使用 AsyncTask,可以讓我們的開(kāi)發(fā)更加順暢。