真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android中,android中查看應(yīng)用程序日志的工具是

在Android系統(tǒng)中如何查看手機(jī)相關(guān)信息

如您需要查看Android系統(tǒng)手機(jī)的相關(guān)信息可以依次點(diǎn)擊進(jìn)入:設(shè)置——關(guān)于手機(jī)。在這個功能里,您可以知道手機(jī)軟件的版本信息、硬件信息、電池狀態(tài)等。(上述內(nèi)容僅適用于廣東聯(lián)通用戶)

創(chuàng)新互聯(lián)自2013年創(chuàng)立以來,先為薛城等服務(wù)建站,薛城等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為薛城企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

探索 Android 中的 Span

在 Android 中,使用 Span 定義文本的樣式. 通過 Span 改變幾個文字的顏色,讓它們可點(diǎn)擊,放縮文字的大小甚至是繪制自定義的項(xiàng)目符號點(diǎn)(bullet points,國外人名中名字之間的間隔符號 · ,HTML 中無序列表項(xiàng)的默認(rèn)符號)。Span 能夠改變 TextPaint 屬性,在 Canvas 上繪制,甚至是改變文本的布局和影響像行高這樣的元素。Span 是可以附加到文本或者從本文分離的標(biāo)記對象(markup objects);它們可以被應(yīng)用到部分或整段的文本中。

讓我們來看看Span如何使用、提供了哪些開箱即用的功能、怎樣簡單地創(chuàng)建我們自己的 Span 以及如何使用和測試它們。

Styling text in Android

Creating custom spans

Testing custom spans implementation

Testing spans usage

Android 提供了幾種定義文本樣式的方法:

單一樣式 使用 XML 屬性或者 樣式和主題 引入了 TextView 的所有內(nèi)容的樣式。這種方式實(shí)現(xiàn)簡單,通過 XML 即可實(shí)現(xiàn),但是并不能只定義部分內(nèi)容的樣式。舉個例子,通過設(shè)置 textStyle=”bold” ,所有的文本都會變?yōu)楹隗w;你不能只定義特定的幾個字符為黑體。

多重樣式 引入了給一段文本添加多種樣式的功能。例如,一個單詞斜體而另一個粗體。多重樣式可以通過使用 HTML 標(biāo)簽、 Span 或者是在 Canvas 上處理自定義的文本繪制。

左圖:單一樣式文本。設(shè)置了 textSize=”32sp” 和 textStyle=”bold” 的 TextView 。右圖:多重樣式文本。設(shè)置了 ForegroundColorSpan, StyleSpan(ITALIC), ScaleXSpan(1.5f), StrikethroughSpan 的文本。

HTML 標(biāo)簽 是解決簡單問題的簡單辦法,例如使文本加粗、斜體,甚至是顯示項(xiàng)目符號點(diǎn)。為了展示含有 HTML 標(biāo)簽的文本,使用 Html.fromHtml 方法。在內(nèi)部實(shí)現(xiàn)時,HTML 標(biāo)簽被轉(zhuǎn)換成了 span 。但是請注意, Html 類并不支持完整的 HTML 標(biāo)簽和 CSS 樣式,例如將小黑點(diǎn)改為其他的顏色。

當(dāng)你有文本樣式的需求,但是 Android 平臺默認(rèn)不支持時,你還可以手動地在 Canvas 上繪制文本,例如讓文字彎曲排布。

Span 允許你實(shí)現(xiàn)具有更細(xì)粒度自定義的多重樣式文本。舉個例子,通過 BulletSpan ,你可以定義你的段落文本擁有項(xiàng)目符號點(diǎn)。你可以定制文本和點(diǎn)號之間的間距和點(diǎn)號的顏色。從 Android P 開始,你甚至可以 設(shè)置點(diǎn)號的半徑 。你也可以創(chuàng)建 span 的自定義實(shí)現(xiàn)。在文章中查看 “創(chuàng)建自定義 span” 部分可以找到如何實(shí)現(xiàn)。

左圖:使用 HTML 標(biāo)簽;中圖:使用 BulletSpan,默認(rèn)圓點(diǎn)大?。挥覉D:在 Android P 上使用 BulletSpan 或者自定義實(shí)現(xiàn)。

你可以組合使用單一樣式和多重樣式。你可以考慮將設(shè)置給 TextView 的樣式作為一種“基本”樣式,而 span 文本樣式是應(yīng)用在基本樣式“之上”并且會覆蓋基本樣式的樣式。例如,當(dāng)給一個 TextView 設(shè)置了 textColor=”@color.blue” 屬性且給頭4個字符應(yīng)用了 ForegroundColorSpan(Color.PINK) ,則頭4個字符會使用 span 設(shè)置的粉色,而其他文本使用 TextView 屬性設(shè)置的顏色。

TextView 組合使用 XML 屬性和 span 樣式

當(dāng)使用 span 時,你會和以下類的其中之一打交道: SpannedString , SpannableString 或 SpannableStringBuilder 。 它們之間的區(qū)別在于文本或標(biāo)記對象是可改變的還是不可改變的以及它們使用的內(nèi)部結(jié)構(gòu): SpannedString 和 SpannableString 使用線性數(shù)組記錄已添加的 span,而 SpannableStringBuilder 使用 區(qū)間樹 。

下面是如何決定使用哪一個的方法:

舉個例子,你用到的文本并不會改變,但你想要附加 span 時,你應(yīng)該使用 SpannableString 。

上面所有的這些類都繼承自 Spanned 接口,但擁有可變標(biāo)記的類( SpannableString 和 SpannableStringBuilder ) 同時也繼承自 Spannable 。

Spanned -- 帶有不可變標(biāo)記的不可變文本

Spannable (繼承自 Spanned) -- 帶有可變標(biāo)記的不可變文本

通過 Spannable 對象調(diào)用 setSpan(Object what, int start, int end, int flags) 方法應(yīng)用 span。 What 對象是一個標(biāo)記,應(yīng)用于從開始到結(jié)束的索引之間的文本。falg 標(biāo)志位標(biāo)記了 span 是否應(yīng)該擴(kuò)展至包含插入文本的開始和結(jié)束的點(diǎn)。任何標(biāo)志位設(shè)置以后,只要插入文本的位置位于開始位置和結(jié)束位置之間,span 就會自動的擴(kuò)展。

舉個例子,設(shè)置 ForegroundColorSpan 可以像下面這樣完成:

因?yàn)?span 設(shè)置時使用了 SPAN_EXCLUSIVE_INCLUSIVE 標(biāo)志位,在 span 的后面插入文本時,新插入的文本也會自動地繼承此 span。

左圖:帶有 ForegroundColorSpan 的文本;右圖:帶有 ForegroundColorSpan 和 Spannable.SPAN_EXCLUSIVE_INCLUSIVE 的文本。

如果 span 設(shè)置了 Spannable.SPAN_EXCLUSIVE_EXCLUSIVE 標(biāo)志位,在 span 后面插入文本時則不會修改 span 的結(jié)束索引。

多個 span 可以被組合且同時附加到同一段文本上。例如,粗體紅色的文本可以像這樣構(gòu)建:

帶有多種 span 的文本:ForegroundColorSpan(Color.RED) 和 StyleSpan(BOLD)

Android framework 定義了幾個接口和抽象類,它們會在測量和渲染時被檢查。這些類有允許 span 訪問像 TextPaint 或 Canvas 對象的方法。

Android framework 在 android.text.style 包、主要接口的字類和抽象類中提供了20+的 span, 我們可以通過下面幾個方式對 span 進(jìn)行分類:

span 類別:字符對比段落,外形對比大小

第一種類型以修改外形的方式在字符級別起作用:文本或背景顏色、下劃線、中橫線等等,它會觸發(fā)文本重新繪制但是并不會重新布局。這些 span 引入了 UpdateAppearance 且繼承自 CharacterStyle . CharacterStyle 字類通過提供更新 TextPaint 的訪問方法,定義了怎樣繪制文本。

影響外形的 span

影響尺寸 的 span 更改了文本的尺寸和布局,因此觀察 span 的變化的對象會重新繪制文本以保證布局和渲染的正確。

舉個例子,影響文本字體大小的 span 要求重新測量和布局,也要求重新繪制。這種 span 通常繼承自 MetricAffectingSpan 類。這個抽象類通過提供對 TextPaint 的訪問,允許字類定義 span 如何影響文本測量,而 MetricAffectingSpan 繼承自 CharacterSpan ,子類在字符級別影響文本的外形。

影響尺寸的 span

你可能會想要一直重新創(chuàng)建帶有文本和標(biāo)記的 CharSequence 并且調(diào)用 TextView.setText(CharSequence) 方法,但是這樣做很有可能一直觸發(fā)已經(jīng)創(chuàng)建好的布局和額外的對象的重新測量和重新繪制。為了減少性能損耗,將文本設(shè)置為 TextView.setText(Spannable, BufferType.SPANNABLE) ,然后當(dāng)你需要更改 span 的時候,通過將 TextView.getText() 轉(zhuǎn)換為 Spannable 從 TextView 獲得 Spannable 對象。我們會在未來的文章中詳細(xì)討論 TextView.setText 的實(shí)現(xiàn)原理和不同的性能優(yōu)化方式。

舉個例子,考慮通過這樣的方式設(shè)置和獲取 Spannable :

現(xiàn)在,當(dāng)我們在 spannableText 上設(shè)置了 span 之后,我們就不需要再調(diào)用 textView.setText 了,因?yàn)槲覀冋谥苯有薷? TextView 持有的 CharSequence 對象的引用。

這是當(dāng)我們設(shè)置了不同的 span 之后會發(fā)生什么:

情形1: 影響外觀的 span

當(dāng)我們附加了一個影響外觀的 span 之后, TextView.onDraw 方法被調(diào)用但 TextView.onLayout 沒有。這是文本重繪,但寬和高保持原樣。

情形2: 影響尺寸的 span

因?yàn)? RelativeSizeSpan 改變了文本的大小,文本的寬和高變化,文本的布局方式(舉個例子,在 TextView 的大小沒有變化的情況下,一個特定的單詞現(xiàn)在可能會換行)。 TextView 需要計(jì)算新的大小所以 onMeasure 和 onLayout 均被調(diào)用。

左圖:ForegroundColorSpan——影響外觀的 span;右圖:RelativeSizeSpan——影響尺寸的 span

一個 span 對文本產(chǎn)生的影響既可以在字符級別,更新元素,如背景顏色、樣式或大小,也可以在段落級別,更改整個文本塊的對齊或者邊距。根據(jù)所需的樣式,span 既可以繼承自 CharacterStyle ,也可以引入 ParagraphStyle 。 繼承自 ParagraphStyle 的 span 必須從第一個字符附加到單個段落的最后一個字符,否則 span 不會被顯示。在 Android 中,段落是基于換行符 (\n) 定義的。

在 Android 中,段落是基于換行符 (\n) 定義的。

影響段落的 span

舉個例子,像 BackgroundColorSpan 這樣的 CharacterStyle ,可以被附加到文本中的任何字符上。這里,我們把它附加到第五到第八個字符上。

ParagraphStyle 的 span,像 QuoteSpan ,只能夠被附加到段落的開始,否則行和文本之間的邊距就不會出現(xiàn)。例如,“Text is\nspantastic” 在文本的第8個字符包含了一個換行符,所以我們可以給它附加一個 QuoteSpan ,段落從那里開始就會被添加樣式。如果我們在0或8之外的任何位置附加 span,text 就不會被添加樣式。

左圖:BackgroundColorSpan -- 影響字符的 span。右圖:QuoteSpan -- 影響段落的 span

在實(shí)現(xiàn)你自己的 span 時,你需要確定你的 span 是否會影響字符或段落級別的文本,以及它是否也會影響文本的布局或外觀。但是,在從頭開始編寫自己的實(shí)現(xiàn)之前,檢查一下是否可以使用 framework 中提供的 span。

太長不看:

假設(shè)我們需要實(shí)現(xiàn)一個 span,它允許以一定的比例增加文本的大小,比如 RelativeSizeSpan ,并設(shè)置文本的顏色,比如 ForegroundColorSpan 。為此,我們可以擴(kuò)展 RelativeSizeSpan ,并且 RelativeSizeSpan 提供了 updateDrawState 和 updateMeasureState 回調(diào),我們可以復(fù)寫繪制狀態(tài)回調(diào)并設(shè)置 TextPaint 的顏色。

注意:同樣的效果可以通過在同一文本上同時應(yīng)用 RelativeSizeSpan 和 ForegroundColorSpan 實(shí)現(xiàn)。

測試 span 意味著檢查確實(shí)已對 TextPaint 進(jìn)行了預(yù)期的修改,或者是否已經(jīng)將正確的元素繪制到了 canvas 上。例如,假設(shè)一個 span 的自定義實(shí)現(xiàn)為段落添加制定大小和顏色的項(xiàng)目符號點(diǎn),以及左邊距和項(xiàng)目符號點(diǎn)之間的間隙。在 android-text sample 查看具體實(shí)現(xiàn)。為了測試這個類,實(shí)現(xiàn)一個 AndroidJUnit 類,確實(shí)檢查:

測試 Canvas 的交互可以通過 mock canvas,給 drawLeadingMargin 方法傳 mock 過的引用并使用正確的參數(shù)驗(yàn)證是否已調(diào)用正確的方法來實(shí)現(xiàn)。

在 BulletPointSpanTest 查看其余的測試。

Spanned 接口允許給文本設(shè)置 span 和從文本獲取 span 。通過實(shí)現(xiàn)一個 Android JUnit 測試,檢查是否在正確的位置添加了正確的 span。在 android-text sample 我們把項(xiàng)目符號點(diǎn)標(biāo)記標(biāo)簽轉(zhuǎn)換為了項(xiàng)目符號點(diǎn)。這是通過給文本在正確的位置附加 BulletPointSpans 。 下面展示了它是如何被測試的:

查看 MarkdownBuilderTest 獲取更多測試示例。

span 是一個非常強(qiáng)大的概念,它深深的嵌入在文本渲染功能中。它們可以訪問 TextPaint 和 Canvas 等組件,這些組件允許在 Android 上使用高度可自定義的文本樣式。在 Android P 中,我們?yōu)?framework span 添加了大量文檔,所以,在實(shí)現(xiàn)你自己的 span 之前,查看那些能夠獲取到的內(nèi)容。

在以后的文章中,我們將向你詳細(xì)介紹 span 在底層是如何工作的以及怎樣高效地使用它們。例如,你需要使用 textView.setText(CharSequence, BufferType) 或者 Spannable.Factory 。 有關(guān)原因的詳細(xì)信息,請保持關(guān)注。

本文原作者 Florina Muntenescu ,Android Developer Advocate @Google . 原文地址: . 本文由 TonnyL 翻譯,發(fā)表在:

Android 中的“子線程”解析

Android 中線程可分為 主線程 和 子線程 兩類,其中主線程也就是 UI線程 ,它的主要這作用就是運(yùn)行四大組件、處理界面交互。子線程則主要是處理耗時任務(wù),也是我們要重點(diǎn)分析的。

首先 Java 中的各種線程在 Android 里是通用的,Android 特有的線程形態(tài)也是基于 Java 的實(shí)現(xiàn)的,所以有必要先簡單的了解下 Java 中的線程,本文主要包括以下內(nèi)容:

在 Java 中要創(chuàng)建子線程可以直接繼承 Thread 類,重寫 run() 方法:

或者實(shí)現(xiàn) Runnable 接口,然后用Thread執(zhí)行Runnable,這種方式比較常用:

簡單的總結(jié)下:

Callable 和 Runnable 類似,都可以用來處理具體的耗時任務(wù)邏輯的,但是但具體的差別在哪里呢?看一個小例子:

定義 MyCallable 實(shí)現(xiàn)了 Callable 接口,和之前 Runnable 的 run() 方法對比下, call() 方法是有返回值的哦,泛型就是返回值的類型:

一般會通過線程池來執(zhí)行 Callable (線程池相關(guān)內(nèi)容后邊會講到),執(zhí)行結(jié)果就是一個 Future 對象:

可以看到,通過線程池執(zhí)行 MyCallable 對象返回了一個 Future 對象,取出執(zhí)行結(jié)果。

Future 是一個接口,從其內(nèi)部的方法可以看出它提供了取消任務(wù)(有坑!?。。?、判斷任務(wù)是否完成、獲取任務(wù)結(jié)果的功能:

Future 接口有一個 FutureTask 實(shí)現(xiàn)類,同時 FutureTask 也實(shí)現(xiàn)了 Runnable 接口,并提供了兩個構(gòu)造函數(shù):

用 FutureTask 一個參數(shù)的構(gòu)造函數(shù)來改造下上邊的例子:

FutureTask 內(nèi)部有一個 done() 方法,代表 Callable 中的任務(wù)已經(jīng)結(jié)束,可以用來獲取執(zhí)行結(jié)果:

所以 Future + Callable 的組合可以更方便的獲取子線程任務(wù)的執(zhí)行結(jié)果,更好的控制任務(wù)的執(zhí)行,主要的用法先說這么多了,其實(shí) AsyncTask 內(nèi)部也是類似的實(shí)現(xiàn)!

注意, Future 并不能取消掉運(yùn)行中的任務(wù),這點(diǎn)在后邊的 AsyncTask 解析中有提到。

Java 中線程池的具體的實(shí)現(xiàn)類是 ThreadPoolExecutor ,繼承了 Executor 接口,這些線程池在 Android 中也是通用的。使用線程池的好處:

常用的構(gòu)造函數(shù)如下:

一個常規(guī)線程池可以按照如下方式來實(shí)現(xiàn):

執(zhí)行任務(wù):

基于 ThreadPoolExecutor ,系統(tǒng)擴(kuò)展了幾類具有新特性的線程池:

線程池可以通過 execute() 、 submit() 方法開始執(zhí)行任務(wù),主要差別從方法的聲明就可以看出,由于 submit() 有返回值,可以方便得到任務(wù)的執(zhí)行結(jié)果:

要關(guān)閉線程池可以使用如下方法:

IntentService 是 Android 中一種特殊的 Service,可用于執(zhí)行后臺耗時任務(wù),任務(wù)結(jié)束時會自動停止,由于屬于系統(tǒng)的四大組件之一,相比一般線程具有較高的優(yōu)先級,不容易被殺死。用法和普通 Service 基本一致,只需要在 onHandleIntent() 中處理耗時任務(wù)即可:

至于 HandlerThread,它是 IntentService 內(nèi)部實(shí)現(xiàn)的重要部分,細(xì)節(jié)內(nèi)容會在 IntentService 源碼中說到。

IntentService 首次創(chuàng)建被啟動的時候其生命周期方法 onCreate() 會先被調(diào)用,所以我們從這個方法開始分析:

這里出現(xiàn)了 HandlerThread 和 ServiceHandler 兩個類,先搞明白它們的作用,以便后續(xù)的分析。

首先看 HandlerThread 的核心實(shí)現(xiàn):

首先它繼承了 Thread 類,可以當(dāng)做子線程來使用,并在 run() 方法中創(chuàng)建了一個消息循環(huán)系統(tǒng)、開啟消息循環(huán)。

ServiceHandler 是 IntentService 的內(nèi)部類,繼承了 Handler,具體內(nèi)容后續(xù)分析:

現(xiàn)在回過頭來看 onCreate() 方法主要是一些初始化的操作, 首先創(chuàng)建了一個 thread 對象,并啟動線程,然后用其內(nèi)部的 Looper 對象 創(chuàng)建一個 mServiceHandler 對象,將子線程的 Looper 和 ServiceHandler 建立了綁定關(guān)系,這樣就可以使用 mServiceHandler 將消息發(fā)送到子線程去處理了。

生命周期方法 onStartCommand() 方法會在 IntentService 每次被啟動時調(diào)用,一般會這里處理啟動 IntentService 傳遞 Intent 解析攜帶的數(shù)據(jù):

又調(diào)用了 start() 方法:

就是用 mServiceHandler 發(fā)送了一條包含 startId 和 intent 的消息,消息的發(fā)送還是在主線程進(jìn)行的,接下來消息的接收、處理就是在子線程進(jìn)行的:

當(dāng)接收到消息時,通過 onHandleIntent() 方法在子線程處理 intent 對象, onHandleIntent() 方法執(zhí)行結(jié)束后,通過 stopSelf(msg.arg1) 等待所有消息處理完畢后終止服務(wù)。

為什么消息的處理是在子線程呢?這里涉及到 Handler 的內(nèi)部消息機(jī)制,簡單的說,因?yàn)?ServiceHandler 使用的 Looper 對象就是在 HandlerThread 這個子線程類里創(chuàng)建的,并通過 Looper.loop() 開啟消息循環(huán),不斷從消息隊(duì)列(單鏈表)中取出消息,并執(zhí)行,截取 loop() 的部分源碼:

dispatchMessage() 方法間接會調(diào)用 handleMessage() 方法,所以最終 onHandleIntent() 就在子線程中劃線執(zhí)行了,即 HandlerThread 的 run() 方法。

這就是 IntentService 實(shí)現(xiàn)的核心,通過 HandlerThread + Hanlder 把啟動 IntentService 的 Intent 從主線程切換到子線程,實(shí)現(xiàn)讓 Service 可以處理耗時任務(wù)的功能!

AsyncTask 是 Android 中輕量級的異步任務(wù)抽象類,它的內(nèi)部主要由線程池以及 Handler 實(shí)現(xiàn),在線程池中執(zhí)行耗時任務(wù)并把結(jié)果通過 Handler 機(jī)制中轉(zhuǎn)到主線程以實(shí)現(xiàn)UI操作。典型的用法如下:

從 Android3.0 開始,AsyncTask 默認(rèn)是串行執(zhí)行的:

如果需要并行執(zhí)行可以這么做:

AsyncTask 的源碼不多,還是比較容易理解的。根據(jù)上邊的用法,可以從 execute() 方法開始我們的分析:

看到 @MainThread 注解了嗎?所以 execute() 方法需要在主線程執(zhí)行哦!

進(jìn)而又調(diào)用了 executeOnExecutor() :

可以看到,當(dāng)任務(wù)正在執(zhí)行或者已經(jīng)完成,如果又被執(zhí)行會拋出異常!回調(diào)方法 onPreExecute() 最先被執(zhí)行了。

傳入的 sDefaultExecutor 參數(shù),是一個自定義的串行線程池對象,所有任務(wù)在該線程池中排隊(duì)執(zhí)行:

可以看到 SerialExecutor 線程池僅用于任務(wù)的排隊(duì), THREAD_POOL_EXECUTOR 線程池才是用于執(zhí)行真正的任務(wù),就是我們線程池部分講到的 ThreadPoolExecutor :

再回到 executeOnExecutor() 方法中,那么 exec.execute(mFuture) 就是觸發(fā)線程池開始執(zhí)行任務(wù)的操作了。

那 executeOnExecutor() 方法中的 mWorker 是什么? mFuture 是什么?答案在 AsyncTask 的構(gòu)造函數(shù)中:

原來 mWorker 是一個 Callable 對象, mFuture 是一個 FutureTask 對象,繼承了 Runnable 接口。所以 mWorker 的 call() 方法會在 mFuture 的 run() 方法中執(zhí)行,所以 mWorker 的 call() 方法在線程池得到執(zhí)行!

同時 doInBackground() 方法就在 call() 中方法,所以我們自定義的耗時任務(wù)邏輯得到執(zhí)行,不就是我們第二部分講的那一套嗎!

doInBackground() 的返回值會傳遞給 postResult() 方法:

就是通過 Handler 將最終的耗時任務(wù)結(jié)果從子線程發(fā)送到主線程,具體的過程是這樣的, getHandler() 得到的就是 AsyncTask 構(gòu)造函數(shù)中初始化的 mHandler , mHander 又是通過 getMainHandler() 賦值的:

可以在看到 sHandler 是一個 InternalHandler 類對象:

所以 getHandler() 就是在得到在主線程創(chuàng)建的 InternalHandler 對象,所以

就可以完成耗時任務(wù)結(jié)果從子線程到主線程的切換,進(jìn)而可以進(jìn)行相關(guān)UI操作了。

當(dāng)消息是 MESSAGE_POST_RESULT 時,代表任務(wù)執(zhí)行完成, finish() 方法被調(diào)用:

如果任務(wù)沒有被取消的話執(zhí)行 onPostExecute() ,否則執(zhí)行 onCancelled() 。

如果消息是 MESSAGE_POST_PROGRESS , onProgressUpdate() 方法被執(zhí)行,根據(jù)之前的用法可以 onProgressUpdate() 的執(zhí)行需要我們手動調(diào)用 publishProgress() 方法,就是通過 Handler 來發(fā)送進(jìn)度數(shù)據(jù):

進(jìn)行中的任務(wù)如何取消呢?AsyncTask 提供了一個 cancel(boolean mayInterruptIfRunning) ,參數(shù)代表是否中斷正在執(zhí)行的線程任務(wù),但是呢并不靠譜, cancel() 的方法注釋中有這么一段:

大致意思就是調(diào)用 cancel() 方法后, onCancelled(Object) 回調(diào)方法會在 doInBackground() 之后被執(zhí)行而 onPostExecute() 將不會被執(zhí)行,同時你應(yīng)該 doInBackground() 回調(diào)方法中通過 isCancelled() 來檢查任務(wù)是否已取消,進(jìn)而去終止任務(wù)的執(zhí)行!

所以只能自己動手了:

AsyncTask 整體的實(shí)現(xiàn)流程就這些了,源碼是最好的老師,自己跟著源碼走一遍有些問題可能就豁然開朗了!


網(wǎng)站標(biāo)題:android中,android中查看應(yīng)用程序日志的工具是
分享鏈接:http://weahome.cn/article/dsdcice.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部