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

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

### 一.基本概念

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

### 二.Android中的進(jìn)程和線程

> 在Android系統(tǒng)中儒陨,如果有一個(gè)應(yīng)用程序組件時(shí)第一次被啟用花嘶,而且這時(shí)候,應(yīng)用程序也沒有其他的組件來運(yùn)行蹦漠,則Android系統(tǒng)會(huì)為應(yīng)用程序創(chuàng)建一個(gè)linux的**進(jìn)程**椭员,這個(gè)Linux進(jìn)程包含一個(gè)**線程**,稱為**主線程**或者**UI線程**.

> 當(dāng)一個(gè)組件在被啟動(dòng)時(shí),如果該process已經(jīng)存在了笛园,那么該組件就直接通過這個(gè)process被啟動(dòng)起來隘击,并且運(yùn)行在這個(gè)process的UI線程中.

#### 1.進(jìn)程

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

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

* <application>中的元素也支持android:proess屬性窄赋,用于指定所有組件的默認(rèn)進(jìn)程。

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

**進(jìn)程有5中層次楼熄,按其重要程度遞減分為**

> 1.前臺(tái)進(jìn)程(用戶當(dāng)前操作所必須的進(jìn)程)

* 擁有一個(gè)正在與用戶交互的Activity

* 擁有一個(gè)Service忆绰,這個(gè)Service綁定了某一個(gè)正在與用戶交互的Activity

* 擁有一個(gè)前臺(tái)Service

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

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

> 2.可見進(jìn)程

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

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

* 擁有一個(gè)Service可岂,這個(gè)Service綁定了一個(gè)可見但是不可與用戶進(jìn)行交互的Activity

> 3.服務(wù)進(jìn)程

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

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

> 4.后臺(tái)進(jìn)程

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

* 系統(tǒng)通過LRU(最近最少使用)列表進(jìn)行多個(gè)后臺(tái)進(jìn)程的管理亚享,確保最近使用的Activity最后被終止

> 5.空進(jìn)程

* 進(jìn)程不含有任何應(yīng)用組件咽块,該進(jìn)程主要作用是緩存,以改善在此進(jìn)程中運(yùn)行組件的啟動(dòng)時(shí)間欺税。

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

#### 3.線程

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

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

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

> 如果卡頓時(shí)間超過5秒,系統(tǒng)就會(huì)報(bào)ANR錯(cuò)誤键耕。所以寺滚,執(zhí)行耗時(shí)的操作,我們需要另起線程執(zhí)行屈雄。

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

> **所有對界面的更新必須在uI線程進(jìn)行**

> 安卓的單線程模式遵從兩個(gè)原則

>

> * 1.不要阻塞UI進(jìn)程

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

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

* 繼承Thread類

* 實(shí)現(xiàn)Runnable接口

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

* Handle + Thread

* AsyncTask

* ThreadPoolExecutor

* IntentService

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

### 三杠氢、實(shí)現(xiàn)多任務(wù)

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

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

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

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

? * AsyncTask機(jī)制

? * Handler機(jī)制

##### (1)使用AsyncTask

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

* 它屏蔽掉了多線程和Handler的概念囤捻,進(jìn)行了較高程度的封裝。

* 使用AsyncTask的代碼很容易被理解邻寿,因?yàn)樗麄兌加幸恍┚哂刑囟氊?zé)的方法蝎土,如:預(yù)處理的方法onPreExecute,后臺(tái)執(zhí)行任務(wù)的方法dolnBackground绣否,更新進(jìn)度的方法publishProgress誊涯,返回結(jié)果的方法onPostExecute等等

##### (2)Handle機(jī)制

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

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

? * Looper:負(fù)責(zé)管理線程的消息隊(duì)列和消息循環(huán)

? * MessageQueue:消息隊(duì)列,先進(jìn)先出段磨,它的作用是保存有待線程處理的消息

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

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

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

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

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

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

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

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

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

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

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

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

* 創(chuàng)建一個(gè)Handler對象债蜜;

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

* 使用post方法運(yùn)行線程對象

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

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

* xml文件中添加一個(gè)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寻定,實(shí)現(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();

? ? ? }


? ? ? /*

? ? ? 這是一個(gè)線程不安全的行為

? ? ? */

? ? ? class ActivityThread extends Thread{

? ? ? ? ? @Override

? ? ? ? ? public void run() {

? ? ? ? ? ? ? try {

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

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

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

? ? ? ? ? ? ? }

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


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

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

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

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

? ? ? ? ? }

? ? ? }

? }

? ```

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

>

> 原因是: 不能在除了UI線程之外的線程里邊進(jìn)行更改UI的操作向胡。

那怎么才能實(shí)現(xiàn)呢浅浮?

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

### 五淮捆、Handler機(jī)制方法調(diào)用

#### 1.使用Runnable和Handler實(shí)現(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{

? ? //寫一個(gè)Handler

? ? Handler countHandler = new Handler();

? ? /*線程1:啟動(dòng)一個(gè)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()表示開機(jī)到當(dāng)前的一個(gè)累計(jì)時(shí)間

? ? ? ? ? ? ? ? */

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

? ? ? ? ? ? ? ? break;

? ? ? ? }

? ? }

}

```

#### 2.開辟一個(gè)工作線程配合Handler實(shí)現(xiàn)計(jì)數(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="啟動(dòng)"/>

? ? <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:啟動(dòng)一個(gè)Toast顯示線程*/

? ? Runnable mRunToast = new Runnable() {

? ? ? ? @Override

? ? ? ? public void run() {

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

? ? ? ? }

? ? };

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

? ? Runnable mRunCount = new Runnable() {

? ? ? ? @Override

? ? ? ? public void run() {

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

? ? ? ? ? ? //再調(diào)用一次,以此形成一個(gè)類似于循環(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()表示開機(jī)到當(dāng)前的一個(gè)累計(jì)時(shí)間

? ? ? ? ? ? ? ? */

? ? ? ? ? ? ? ? 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;

? ? ? ? }

? ? }

}

```

運(yùn)行效果;

![在這里插入圖片描述](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實(shí)現(xiàn)多任務(wù)

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

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

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

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

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

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

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

* Android提供一個(gè)讓程序員編寫后臺(tái)操作更為容易和透明AsyncTask,使得后臺(tái)線程能夠在UI主線程外進(jìn)行處理

* 使用AsyncTask蟆盐,不需要自己來寫后臺(tái)線程,無需終結(jié)后臺(tái)線程遭殉,只需要?jiǎng)?chuàng)建AsyncTask類石挂,并實(shí)現(xiàn)其中的抽象方法以及重寫某些方法

> 下面是一個(gè)實(shí)例,點(diǎn)擊按鈕险污,啟動(dòng)進(jìn)度條痹愚。進(jì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");

? ? ? ? ? ? //更新進(jìn)度條

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

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

? ? ? ? }

? ? ? ? /**

? ? ? ? 這個(gè)方法是使用AsyncTask必須進(jìn)行覆寫的一個(gè)方法蛔糯,耗時(shí)的操作在此方法內(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í)行此操作會(huì)自動(dòng)調(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)

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

> 運(yùn)行效果:

![在這里插入圖片描述](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.實(shí)現(xiàn)步驟

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

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

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

? **這個(gè)方法是AsyncTask的關(guān)鍵蚁飒,必須進(jìn)行覆寫**

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末动壤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子飒箭,更是在濱河造成了極大的恐慌狼电,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弦蹂,死亡現(xiàn)場離奇詭異肩碟,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凸椿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門削祈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人脑漫,你說我怎么就攤上這事髓抑。” “怎么了优幸?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵吨拍,是天一觀的道長。 經(jīng)常有香客問我网杆,道長羹饰,這世上最難降的妖魔是什么伊滋? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮队秩,結(jié)果婚禮上笑旺,老公的妹妹穿的比我還像新娘。我一直安慰自己馍资,他們只是感情好筒主,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸟蟹,像睡著了一般乌妙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上戏锹,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天冠胯,我揣著相機(jī)與錄音,去河邊找鬼锦针。 笑死荠察,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奈搜。 我是一名探鬼主播悉盆,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼馋吗!你這毒婦竟也來了焕盟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宏粤,失蹤者是張志新(化名)和其女友劉穎脚翘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绍哎,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡来农,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了崇堰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沃于。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖海诲,靈堂內(nèi)的尸體忽然破棺而出繁莹,到底是詐尸還是另有隱情,我是刑警寧澤特幔,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布咨演,位于F島的核電站,受9級特大地震影響蚯斯,放射性物質(zhì)發(fā)生泄漏雪标。R本人自食惡果不足惜零院,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望村刨。 院中可真熱鬧,春花似錦撰茎、人聲如沸嵌牺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逆粹。三九已至,卻和暖如春炫惩,著一層夾襖步出監(jiān)牢的瞬間僻弹,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工他嚷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蹋绽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓筋蓖,卻偏偏與公主長得像卸耘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子粘咖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

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