安卓多任務(wù)實現(xiàn)的基本原理

## 安卓多任務(wù)實現(xiàn)的基本原理

### 一.基本概念

>? 操作一些耗時操作時候,如I/O讀寫大文件,數(shù)據(jù)庫操作以及網(wǎng)絡(luò)下載需要很長時間,為了不阻塞用戶界面,出現(xiàn)ANR(應(yīng)用程序無響應(yīng))的響應(yīng)提示窗口,這個時候我們考慮使用Thread線程來進行解決.? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

### 二.Android中的進程和線程

> 在Android系統(tǒng)中,如果有一個應(yīng)用程序組件時第一次被啟用,而且這時候,應(yīng)用程序也沒有其他的組件來運行,則Android系統(tǒng)會為應(yīng)用程序創(chuàng)建一個linux的**進程**,這個Linux進程包含一個**線程**,稱為**主線程**或者**UI線程**.

> 當一個組件在被啟動時,如果該process已經(jīng)存在了,那么該組件就直接通過這個process被啟動起來,并且運行在這個process的UI線程中.

#### 1.進程

* 默認情況下,同一個應(yīng)用程序內(nèi)的所有組件都是運行在同一個進程中的,大部分應(yīng)用程序都是按照這種方式運行的;

* 在具體應(yīng)用中,很多時候需要通過在manifest文件中進行設(shè)置,通過修改四大組件在Manifest.xml的代碼塊中的android:proess屬性指定組件運行的進程,使其運行在不同的process中。

* <application>中的元素也支持android:proess屬性,用于指定所有組件的默認進程。

#### 2.進程的重要性層次結(jié)構(gòu)

**進程有5中層次,按其重要程度遞減分為**

> 1.前臺進程(用戶當前操作所必須的進程)

* 擁有一個正在與用戶交互的Activity

* 擁有一個Service,這個Service綁定了某一個正在與用戶交互的Activity

* 擁有一個前臺Service

* 擁有一個Service且它正在執(zhí)行聲明周期回調(diào)方法

* 擁有一個BroadcastReceiver且這個BroadcastReceiver正在執(zhí)行onRece方法

> 2.可見進程

* 沒有任何前臺組件,但是仍然會影響用戶在屏幕上所見內(nèi)容的進程

* 擁有一個可見但是不可與用戶交互的Activity

* 擁有一個Service,這個Service綁定了一個可見但是不可與用戶進行交互的Activity

> 3.服務(wù)進程

* 由startService()方法啟動的Service進程,雖然不直接和所見內(nèi)容關(guān)聯(lián),但是會執(zhí)行一些用戶關(guān)心的操作,例如后臺播放音樂或者下載數(shù)據(jù)等等

* 若系統(tǒng)不足以維持前臺進程和可見進程,才會犧牲服務(wù)進程的空間

> 4.后臺進程

* 包含用戶不可見的Activity的進程,這些進程對用戶體驗沒有直接影響,可以隨時在任意時間終止它們,以回收內(nèi)存資源.

* 系統(tǒng)通過LRU(最近最少使用)列表進行多個后臺進程的管理,確保最近使用的Activity最后被終止

> 5.空進程

* 進程不含有任何應(yīng)用組件,該進程主要作用是緩存,以改善在此進程中運行組件的啟動時間。

* 系統(tǒng)會經(jīng)常終正此類進程

#### 3.線程

> Android是單線程模型,我們創(chuàng)建的Service、Activity以及Broadcast均是在一個主線程處理,這里我們可以理解為uI線程。(應(yīng)用程序是一個默認的**單線程單任務(wù)程序**)

> Ul Thread中運行著許多重要的邏輯,如系統(tǒng)事件處理,用戶輸入事件處理,ul繪制,Service,Alarm等

> 我們編寫的代碼穿插在主線程的邏輯中,比如對用戶觸摸事件的檢測和響應(yīng),對用戶輸入的處理,自定義View的繪制等。如果我們插入的代碼比價耗時,如網(wǎng)絡(luò)請求或數(shù)據(jù)庫讀取,就會阻塞uI線程其他邏輯的執(zhí)行,從而導致界面卡頓。

> 如果卡頓時間超過5秒,系統(tǒng)就會報ANR錯誤。所以,執(zhí)行耗時的操作,我們需要另起線程執(zhí)行。

> 在新線程執(zhí)行完耗時的邏輯后,往往需要將結(jié)果反饋給界面,進行uI更新。Android的ul toolkit不是線程安全的,不能在非uI線程進行uI的更新

> **所有對界面的更新必須在uI線程進行**

> 安卓的單線程模式遵從兩個原則

>

> * 1.不要阻塞UI進程

> * 2.不要在UI線程之外訪問UI組件

> 創(chuàng)建線程:? 基礎(chǔ)操作都在UI線程中運行,耗時操作可以創(chuàng)建新的線程去完成

* 繼承Thread類

* 實現(xiàn)Runnable接口

> **安卓提供的四種常用的操作多線程的方式,分別是:**

* Handle + Thread

* AsyncTask

* ThreadPoolExecutor

* IntentService

————————————————————————————————————————————————————————————————————

### 三、實現(xiàn)多任務(wù)

#### 1.多任務(wù)的實現(xiàn)原理

* **在Android中,我們把除uI線程外的,其他所有的線程都叫做工作線程,也就是說Android只會存在兩種線程:UI主線程(ul thread)和工作線程(work thread)**

* 我們把耗時的操作放在工作線程中去做。操作完成后,再通知UI主線程做出相應(yīng)的響應(yīng)。

* 這就需要掌握線程間通信的方式。在Android中提供了兩種線程間的通信方式:

? * AsyncTask機制

? * Handler機制

##### (1)使用AsyncTask

* AsyncTask是Android框架提供的**異步處理**的輔助類,它可以實現(xiàn)耗時操作仕具他線程執(zhí)行,而處理結(jié)果在Main線程執(zhí)行

* 它屏蔽掉了多線程和Handler的概念,進行了較高程度的封裝。

* 使用AsyncTask的代碼很容易被理解,因為他們都有一些具有特定職責的方法,如:預(yù)處理的方法onPreExecute,后臺執(zhí)行任務(wù)的方法dolnBackground,更新進度的方法publishProgress,返回結(jié)果的方法onPostExecute等等

##### (2)Handle機制

* Handler機制是通過消息隊列進行通信的機制,通過使用Handler,LooperMessageQueue,和Message這幾個類協(xié)調(diào)來完成

? * Handler:在android里負責發(fā)送和處理消息,通過它可以實現(xiàn)其他線程與Main線程之間的消息通訊

? * Looper:負責管理線程的消息隊列和消息循環(huán)

? * MessageQueue:消息隊列,先進先出,它的作用是保存有待線程處理的消息

#####? ? (3)Handler類

* UI主線程在創(chuàng)建時會被自動創(chuàng)建一個消息隊列和消息循環(huán),主線程的Looper通過創(chuàng)建一個Handler對象,對外界提供了訪問消息隊列的渠道

? * 主線程通過Handler.handleMessage()讀取消息隊列中的消息

? * 工作線程通過方法發(fā)送消息到主線程的消息隊列**Handler.sendMessage()? ? Handler.post()**

————————————————————————————————————————————————————————————————

### 四、.Android實現(xiàn)多線程的兩種操作模式

#### 1Android有兩種方式實現(xiàn)多線程操作UI:

* 第一種是創(chuàng)建新線程Thread,用handler負責線程間的通信和消息。

* 第二種方式AsyncTask異步執(zhí)行任務(wù)

#### 2.使用Handler實現(xiàn)多任務(wù)

在新的線程中調(diào)用主線程中的Handler的postXX和sendmessage方法來實現(xiàn)與主線程進行通信

**使用post方法實現(xiàn)多任務(wù)的主要步驟**:

* 創(chuàng)建一個Handler對象;

* 將要執(zhí)行的操作卸載線程對象的run方法中;

* 使用post方法運行線程對象

* 如果需要循環(huán)執(zhí)行,需要在線程對象的run方法中再次調(diào)用post方法

#### 3.Handler機制實現(xiàn)異步任務(wù)demo

* xml文件中添加一個TextView

? ```xml

? <?xml version="1.0" encoding="utf-8"?>

? <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? ? xmlns:app="http://schemas.android.com/apk/res-auto"

? ? ? xmlns:tools="http://schemas.android.com/tools"

? ? ? android:layout_width="match_parent"

? ? ? android:layout_height="match_parent"

? ? ? tools:context=".AsynchronousTask.HandlerAsyTaskActivity">


? ? ? <TextView

? ? ? ? ? android:id="@+id/textview"

? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? android:text="hello"

? ? ? ? ? android:textAllCaps="false"

? ? ? ? ? tools:ignore="MissingConstraints" />



? </androidx.constraintlayout.widget.ConstraintLayout>

? ```

* java文件 編輯代碼

? ```java

? package com.example.handleractivity.AsynchronousTask;


? import androidx.annotation.NonNull;

? import androidx.appcompat.app.AppCompatActivity;


? import android.os.Bundle;

? import android.os.Handler;

? import android.os.Message;

? import android.widget.TextView;


? import com.example.handleractivity.R;


? public class HandlerAsyTaskActivity extends AppCompatActivity {


? ? ? private final static int TEST = 1;


? ? ? private TextView textView;


? ? ? //這是自己創(chuàng)建的Handler,實現(xiàn)異步任務(wù),這里用來更改UI

? ? ? private Handler mHandler = new Handler(){

? ? ? ? ? @Override

? ? ? ? ? public void handleMessage(@NonNull Message msg) {

? ? ? ? ? ? ? textView.setText("這是工作線程文本");

? ? ? ? ? }

? ? ? };



? ? ? @Override

? ? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? ? setContentView(R.layout.activity_handler_asy_task);


? ? ? ? ? textView = findViewById(R.id.textview);

? //? ? ? ? textView.setText("這是一段文本");

? ? ? ? ? new ActivityThread().start();

? ? ? }


? ? ? /*

? ? ? 這是一個線程不安全的行為

? ? ? */

? ? ? class ActivityThread extends Thread{

? ? ? ? ? @Override

? ? ? ? ? public void run() {

? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? Thread.sleep(3000);

? ? ? ? ? ? ? } catch (InterruptedException e) {

? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? }

? //? ? ? ? ? ? textView.setText("這是工作線程文本");


? ? ? ? ? ? ? //使用handler發(fā)送消息至消息隊列

? ? ? ? ? ? ? Message message = new Message();

? ? ? ? ? ? ? message.what = TEST;

? ? ? ? ? ? ? mHandler.sendMessage(message);

? ? ? ? ? }

? ? ? }

? }

? ```

> 我們設(shè)置一個線程,讓其休眠3秒鐘,然后執(zhí)行 textView.setText("這是工作線程文本")操作,三秒之后程序會崩潰。

>

> 原因是: 不能在除了UI線程之外的線程里邊進行更改UI的操作。

那怎么才能實現(xiàn)呢?

> 使用Handler實現(xiàn)異步任務(wù),自己新建一個Handler,然后在工作線程中使用handler來傳遞信息。handler里面進行更改UI的操作,就可了

### 五、Handler機制方法調(diào)用

#### 1.使用Runnable和Handler實現(xiàn)五秒鐘之后出現(xiàn)彈窗

```xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? xmlns:app="http://schemas.android.com/apk/res-auto"

? ? xmlns:tools="http://schemas.android.com/tools"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent"

? ? tools:context=".HandlerPost.HandlerPostActivity">

? ? <Button

? ? ? ? android:id="@+id/btnShowToast"

? ? ? ? android:layout_width="wrap_content"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="開啟Toast"/>

? ? <TextView

? ? ? ? android:text="你好"

? ? ? ? android:layout_width="wrap_content"

? ? ? ? android:layout_height="wrap_content"/>

</LinearLayout>

```

```java

public class HandlerPostActivity extends AppCompatActivity implements View.OnClickListener{

? ? //寫一個Handler

? ? Handler countHandler = new Handler();

? ? /*線程1:啟動一個Toast顯示線程*/

? ? Runnable mRunToast = new Runnable() {

? ? ? ? @Override

? ? ? ? public void run() {

? ? ? ? ? ? Toast.makeText(HandlerPostActivity.this,"hello Toast",Toast.LENGTH_SHORT).show();

? ? ? ? }

? ? };

? ? private Button mbtnShowToast;

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_handler_post);

? ? ? ? mbtnShowToast = findViewById(R.id.btnShowToast);

? ? ? ? mbtnShowToast.setOnClickListener(this);

? ? }

? ? //添加事件監(jiān)聽

? ? @Override

? ? public void onClick(View v) {

? ? ? ? switch (v.getId()) {

? ? ? ? ? ? case R.id.btnShowToast:

? ? ? ? ? ? ? ? /**

? ? ? ? ? ? ? ? * SystemClock.uptimeMillis()表示開機到當前的一個累計時間

? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? countHandler.postAtTime(mRunToast, SystemClock.uptimeMillis()+5*1000);

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? }

}

```

#### 2.開辟一個工作線程配合Handler實現(xiàn)計數(shù)器的功能

```xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? xmlns:app="http://schemas.android.com/apk/res-auto"

? ? xmlns:tools="http://schemas.android.com/tools"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent"

? ? tools:context=".HandlerPost.HandlerPostActivity"

? ? android:orientation="vertical">

? ? <Button

? ? ? ? android:id="@+id/btnStart"

? ? ? ? android:layout_width="wrap_content"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="啟動"/>

? ? <Button

? ? ? ? android:id="@+id/btnStop"

? ? ? ? android:layout_width="wrap_content"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="關(guān)閉"/>

? ? <Button

? ? ? ? android:id="@+id/btnShowToast"

? ? ? ? android:layout_width="wrap_content"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="開啟Toast"/>

? ? <TextView

? ? ? ? android:id="@+id/tvCount"

? ? ? ? android:text="你好"

? ? ? ? android:layout_width="wrap_content"

? ? ? ? android:layout_height="wrap_content"/>

</LinearLayout>

```

```java

public class HandlerPostActivity extends AppCompatActivity implements View.OnClickListener {

? ? Handler countHandler = new Handler();

? ? int count = 0;

? ? /*線程1:啟動一個Toast顯示線程*/

? ? Runnable mRunToast = new Runnable() {

? ? ? ? @Override

? ? ? ? public void run() {

? ? ? ? ? ? Toast.makeText(HandlerPostActivity.this, "hello Toast", Toast.LENGTH_SHORT).show();

? ? ? ? }

? ? };

? ? /*線程2:文本區(qū)計數(shù)器線程*/

? ? Runnable mRunCount = new Runnable() {

? ? ? ? @Override

? ? ? ? public void run() {

? ? ? ? ? ? textCount.setText("count: " + String.valueOf(count++));

? ? ? ? ? ? //再調(diào)用一次,以此形成一個類似于循環(huán)的操作,一秒加一次

? ? ? ? ? ? countHandler.postDelayed(mRunCount, 1000);

? ? ? ? }

? ? };

? ? private Button mbtnShowToast;

? ? private TextView textCount;

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_handler_post);

? ? ? ? mbtnShowToast = findViewById(R.id.btnShowToast);

? ? ? ? mbtnShowToast.setOnClickListener(this);

? ? ? ? findViewById(R.id.btnStart).setOnClickListener(this);

? ? ? ? findViewById(R.id.btnStop).setOnClickListener(this);

? ? ? ? textCount = findViewById(R.id.tvCount);

? ? }

? ? //添加事件監(jiān)聽

? ? @Override

? ? public void onClick(View v) {

? ? ? ? switch (v.getId()) {

? ? ? ? ? ? case R.id.btnShowToast:

? ? ? ? ? ? ? ? /**

? ? ? ? ? ? ? ? * SystemClock.uptimeMillis()表示開機到當前的一個累計時間

? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? countHandler.postAtTime(mRunToast, SystemClock.uptimeMillis() + 5 * 1000);

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case R.id.btnStart:

? ? ? ? ? ? ? ? //表示推遲一秒執(zhí)行

? ? ? ? ? ? ? ? countHandler.postDelayed(mRunCount, 1000);

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? case R.id.btnStop:

? ? ? ? ? ? ? ? //移除回調(diào)的過程

? ? ? ? ? ? ? ? countHandler.removeCallbacks(mRunCount);

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? }

}

```

運行效果;

![在這里插入圖片描述](https://img-blog.csdnimg.cn/20210616152014880.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3R3ZW50eV9mb3VyXzc=,size_16,color_FFFFFF,t_70#pic_center)

### 六、AsyncTask實現(xiàn)多任務(wù)

* 使用Handler類來在子線程中更新UI線程總會啟動一些匿名的子線程,太多的子線程給系統(tǒng)帶來了巨大的負擔

* Andoroid提供了一個工具類AdyncTask,來實現(xiàn)異步執(zhí)行任務(wù)

* AsyncTask是抽象類,具有三種泛型:Params、Progress、Result

? * **Params: **表示啟動任務(wù)執(zhí)行的參數(shù),比如HTTP請求的URL

? * **Progress:** 表示后臺任務(wù)執(zhí)行的百分比

? * **Result: **表示后臺執(zhí)行任務(wù)最終返回的結(jié)果,比如String,Integer等

* 通過繼承一個AsyncTask類定義一個異步任務(wù)類

* Android提供一個讓程序員編寫后臺操作更為容易和透明AsyncTask,使得后臺線程能夠在UI主線程外進行處理

* 使用AsyncTask,不需要自己來寫后臺線程,無需終結(jié)后臺線程,只需要創(chuàng)建AsyncTask類,并實現(xiàn)其中的抽象方法以及重寫某些方法

> 下面是一個實例,點擊按鈕,啟動進度條。進度條加載完畢,把“執(zhí)行完畢”顯示在文本上

#### 1.xml文件

```xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? xmlns:app="http://schemas.android.com/apk/res-auto"

? ? xmlns:tools="http://schemas.android.com/tools"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent"

? ? android:orientation="vertical"

? ? tools:context=".AsynchronousTask.AsyncTaskDemo">

? ? <Button

? ? ? ? android:id="@+id/btn"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:text="Press it"

? ? ? ? android:textAllCaps="false" />

? ? <TextView

? ? ? ? android:id="@+id/txt"

? ? ? ? android:layout_width="wrap_content"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:layout_gravity="center"

? ? ? ? android:textSize="30sp"

? ? ? ? android:text="hello world" />

? ? <ProgressBar

? ? ? ? android:id="@+id/progressbar"

? ? ? ? style="@style/Widget.AppCompat.ProgressBar.Horizontal"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="wrap_content"

? ? ? ? android:visibility="invisible"

? ? ? ? android:layout_marginTop="50dp" />

</LinearLayout>

```

#### 2.java文件

```java

public class AsyncTaskDemo extends AppCompatActivity implements View.OnClickListener {

? ? private final static String TAG = "AsyncTaskDemo";

? ? private Button mBtn;

? ? private ProgressBar progressBar;

? ? private TextView mTxt;

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_async_task_demo);

? ? ? ? mBtn = findViewById(R.id.btn);

? ? ? ? mBtn.setOnClickListener(this);

? ? ? ? progressBar = findViewById(R.id.progressbar);

? ? ? ? mTxt = findViewById(R.id.txt);

? ? }

? ? @Override

? ? public void onClick(View v) {

? ? ? ? TimeTickLoad timeTickLoad = new TimeTickLoad();

? ? ? ? timeTickLoad.execute(1000);

? ? }

? ? class TimeTickLoad extends AsyncTask<Integer,Integer,String>{

? ? ? ? @Override

? ? ? ? protected void onPreExecute() {

? ? ? ? ? ? Log.i(TAG, "onPreExecute");

? ? ? ? ? ? progressBar.setVisibility(ProgressBar.VISIBLE);

? ? ? ? ? ? super.onPreExecute();

? ? ? ? }

? ? ? ? @Override

? ? ? ? protected void onPostExecute(String s) {

? ? ? ? ? ? Log.i(TAG, "onPostExecute");

? ? ? ? ? ? super.onPostExecute(s);

? ? ? ? ? ? mTxt.setText(s);

? ? ? ? }

? ? ? ? @Override

? ? ? ? protected void onProgressUpdate(Integer... values) {

? ? ? ? ? ? mTxt.setText("onProgressUpdate");

? ? ? ? ? ? Log.i(TAG, "onProgressUpdate");

? ? ? ? ? ? //更新進度條

? ? ? ? ? ? progressBar.setProgress(values[0]);

? ? ? ? ? ? super.onProgressUpdate(values);

? ? ? ? }

? ? ? ? /**

? ? ? ? 這個方法是使用AsyncTask必須進行覆寫的一個方法,耗時的操作在此方法內(nèi)執(zhí)行

? ? ? ? */

? ? ? ? @Override

? ? ? ? protected String doInBackground(Integer... integers) {

? ? ? ? ? ? //這里不能撰寫UI相關(guān)操作

? ? ? ? ? ? Log.i(TAG, "hello");

//? ? ? ? ? ? mTxt.setText("doInBackground");

? ? ? ? ? ? for (int i = 0; i < 10; i++) {

? ? ? ? ? ? ? ? //執(zhí)行此操作會自動調(diào)用onProgressUpdate()

? ? ? ? ? ? ? ? publishProgress(i*10);

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? Thread.sleep(integers[0]);

? ? ? ? ? ? ? ? }catch (Exception e){

? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ? ? return "執(zhí)行完畢";

? ? ? ? }

? ? }

}

```

> AsyncTask的周期:

![在這里插入圖片描述](https://img-blog.csdnimg.cn/20210616152048240.png#pic_center)

**從打印的日志可以看出,首先運行的是onPreExecute()方法,然后運行的是doInBackground(),最后運行的是onPostExecute**

> 運行效果:

![在這里插入圖片描述](https://img-blog.csdnimg.cn/20210616152057393.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3R3ZW50eV9mb3VyXzc=,size_16,color_FFFFFF,t_70#pic_center)

#### 3.實現(xiàn)步驟

* 使用execute方法出發(fā)異步任務(wù)的執(zhí)行

* 使用onPreExecute()表示執(zhí)行預(yù)處理 : 在本例中實現(xiàn)繪制一個進度條控件

* 使用doInBackground()用于執(zhí)行較為費時的操作:在本例中就是計算進度

? **這個方法是AsyncTask的關(guān)鍵,必須進行覆寫**

* 使用onProgressUpdate()對進度條控件根據(jù)進度值做出具體的響應(yīng)

* 使用onPostExecute()可以對后臺任務(wù)的結(jié)果做出處理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容