Android中的多線程「安全」

2021-02-20 搜狗測試

Android沿用了JAVA的線程模型,其中的線程分為主線程和子線程,其中主線程又叫UI線程。在Android系統中,在默認情況下,一個應用程式內的各個組件(如Activity、BroadcastReceiver、Service)都會在同一個進程(Process)裡執行,且由此進程的主線程負責執行。如果有特別指定(通過android:process),也可以讓特定組件在不同的進程中運行。無論組件在哪一個進程中運行,默認情況下,他們都由此進程的主線程負責執行。主線程既要處理Activity組件的UI事件,又要處理Service後臺服務工作,通常會忙不過來。為了解決此問題,主線程可以創建多個子線程來處理後臺服務工作,而本身專心處理UI畫面的事件。子線程的任務則是執行耗時任務,比如網絡請求,I/O操作等。

Android中的子線程

Android中開啟一個子線程,有以下兩種方法:第一種是類繼承Thread重寫run方法,第二種是實習Runnable接口並重寫run方法。

1:繼承Thread類

public class MyThread extendsThread { 

   public void run(){ 

   } 

}

newMyThread().start();

2:實現Runnable接口

public class MyRunnable implementsRunnable{

@Override

public void run(){

   } 

}

new MyThread().start();

Android提供了好幾種方法讓其他線程操作UI控制項:

Activity.runOnUiThread(Runnable)、View.post(Runnable)、Handler。

這些類或方法代碼比較複雜,因此Android提供了一個名為AsyncTask的輔助類來簡化多線程代碼。

AsyncTask

AsyncTask是一個輕量級的異步任務類,它可以在線程池中執行後臺任務,然後把執行的進度和結果傳遞給主線程並且在主線程中更新UI。AsyncTask適用於簡單的異步處理,不需要藉助線程和Handler即可實現。

AsyncTask是抽象類,定義了三種泛型類型Params,Progress和Result。

(1).Params啟動任務執行的輸入參數,比如HTTP請求的URL。

(2).Progress後臺任務執行的百分比。

(3).Result後臺執行任務最終返回的結果,比如String。

AsyncTask後臺線程與UI線程的交互如下圖:

AsyncTask後臺線程與UI線程的交互

(1).onPreExecute(),該方法將在執行實際的後臺操作前被UI thread調用。

(2).doInBackground(Params...),將在onPreExecute方法執行後馬上執行,該方法運行在後臺線程中,這裡將主要負責執行那些很耗時的後臺計算工作。

(3).onProgressUpdate(Progress...),在publishProgress方法被調用後,UI thread將調用這個方法從而在界面上展示任務的進展情況。

(4).onPostExecute(Result),在doInBackground執行完成後,onPostExecute 方法將被UI thread調用,後臺的計算結果將通過該方法傳遞到UI thread。

相關焦點

  • Android中多線程的使用四種方式最全總結
    通常一個應用的所有組件都運行在這一個Process中,當然,你可以通過修改四大組件在Manifest.xml中的代碼塊(<activity><service><provider><receiver>)中的android:process屬性指定其運行在不同的process中。
  • 為什麼會有多線程?什麼是線程安全?如何保證線程安全?
    什麼是線程安全?怎麼樣保證線程安全?為什麼會有多線程顯然,線程安全的問題只會出現在多線程環境中,那麼為什麼會有多線程呢?最早期的計算機十分原始,還沒有作業系統。想要使用計算機時,人們先把計算機可以執行的指令刻在紙帶上,然後讓計算機從紙帶上讀取每一條指令,依次執行。這時候的計算機每次只能執行一個任務,是地地道道的單線程。
  • Spring 中的 Bean 是線程安全的嗎?
    結論:不是線程安全的Spring容器中的Bean是否存在線程安全,容器本身並沒有提供Bean的線程安全策略,因此可以說Spring容器中的Bean本身不具有線程安全的特性,但是具體還是要結合具體的scope進行。
  • Spring 中的bean 是線程安全的嗎?
    結論:不是線程安全的Spring容器中的Bean是否線程安全,容器本身並沒有提供Bean的線程安全策略,因此可以說Spring容器中的Bean本身不具備線程安全的特性,但是具體還是要結合具體scope的Bean去研究。
  • Android子線程也能修改UI?
    XXX:為什麼我的控制項可以在子線程裡面更新我(不假思索):你是不是在onCreate裡面開了一個子線程,然後更新了UIXXX:好像是這樣。。我:你試試將子線程沉睡5秒鐘時間,應該就會閃退了XXX:我試試。N分鐘以後.
  • Android 子線程也能修改 UI?
    我(不假思索):你是不是在onCreate裡面開了一個子線程,然後更新了UIXXX:好像是這樣。。我:你試試將子線程沉睡5秒鐘時間,應該就會閃退了XXX:我試試。N分鐘以後.XXX:我加了沉睡時間,還是不會閃退我:讓我看一下截圖吧他的onResume方法是自定義的,在系統onResume方法中調用,但是依然沒有閃退。這個時候我的腦子也是一篇懵逼的。如果是onCreate開了子線程,然後子線程立刻更新UI,那是不會出現閃退的。
  • 精選Android高級面試題 : 深探Handler,多線程,Bitmap
    參考回答:Android的UI控制項不是線程安全的,如果在多線程中並發訪問可能會導致UI控制項處於不可預期的狀態。這時你可能會問為何系統不對UI控制項的訪問加上鎖機制呢?因為:6、Looper死循環為什麼不會導致應用卡死?
  • 線程安全?關於ArrayMap被誤用的細節與解決方法
    freeArrays(mHashes, mArray, mSize);        mHashes = ContainerHelpers.EMPTY_INTS;//先回收,再賦值        mArray = ContainerHelpers.EMPTY_OBJECTS;        mSize = 0;    }}如何驗證我們的分析:前面我們查看源碼知道ArrayMap是非線程安全的
  • 在 Android 開發中使用協程 | 背景介紹
    ;保證主線程安全 (Main-safety) ,即確保安全地從主線程調用任何 suspend 函數。接下來,讓我們來看一下協程是如何保證主線程安全 (main-safety),並來探討一下調度器。在 Kotlin 的協程中,主線程調用編寫良好的 suspend 函數通常是安全的。不管那些 suspend 函數是做什麼的,它們都應該允許任何線程調用它們。
  • iOS多線程全套:線程生命周期,多線程的四種解決方案,線程安全問題,GCD的使用,NSOperation的使用(上)
    主線程:處理UI,所有更新UI的操作都必須在主線程上執行。不要把耗時操作放在主線程,會卡界面。多線程:在同一時刻,一個CPU只能處理1條線程,但CPU可以在多條線程之間快速的切換,只要切換的足夠快,就造成了多線程一同執行的假象。線程就像火車的一節車廂,進程則是火車。車廂(線程)離開火車(進程)是無法跑動的,而火車(進程)至少有一節車廂(主線程)。
  • 多線程安全——鎖
    Peterson解法#define FALSE 0#define TRUE 1#define N    2                  int turn; int interested[N]; void enter_region(int process){    int
  • fork()函數與Linux中的多線程編程
    很多程序中都存在全局對象,這些全局對象的初始化工作都是在進入main()函數之前進行的,為了能保證全局對象的安全初始化(按順序的),因此在程序進入main()函數之前應該避免線程的創建,從而杜絕未知錯誤的發生。三、fork()與多線程在程序中fork()與多線程的協作性很差,這是POSIX系列作業系統的歷史包袱。
  • Android多線程:全面了解AsyncTask & 具體使用
    前言   在Android開發的多線程應用場景中,AsyncTask十分常用。
  • Android中AIDL的基本用法
    Kangel Zenn的博客地址:https://flrito.cc文章屬於基礎類型的,但是AIDL平時開發中可能寫的也不多,可以閱讀下權當複習了,此外感覺作者文筆很不錯,寫的也很清晰,期待他的其他文章~早些時候就聽說過AIDL,也常在各種Android面試題、教程甚至大牛採訪中看到過它的身影。
  • Swift 中的鎖和線程安全
    幸運的是,蘋果系統的 API 可以非常容易地應用到 Swift 中。今天,我會介紹這些 API 的用法以及從 Objective-C 過渡的一些問題,這些靈感都來源於 Cameron Pulsford。快速回顧一下鎖鎖(lock)或者互斥鎖(mutex)是一種結構,用來保證一段代碼在同一時刻只有一個線程執行。它們通常被用來保證多線程訪問同一可變數據結構時的數據一致性。
  • 【專業知識】Android主線程的消息系統(Handler\Looper)
    前言:之前的文章寫的都是關於Bitmap和內存的優化技術,這一篇文章給大家談談Handler。Handler是Android系統中比較重要的一個知識,在Android多線程面試經常會被問到,在實際項目中的確也經常用到。當然也比較複雜,知識比較多,牽扯到的類有Thread、Looper、Message、MessageQueue。
  • java學習|圖說多線程(一)那些孿生的線程(不)安全的類
    在上面三組類中,開發時我們大都是使用的上面的,如使用StringBuilder做String拼接。 使用ArrayList存儲資料庫返回的一組數據, 用HashMap傳參等等。因為現在開發大都是在SpringMVC下開發,全局變量都是一些Manager, Service,Mapper之類的。
  • 多線程使用for循環遍歷同一個Set,是否線程安全?
    情景:        有一個線程外部的set集合(值保持不變),有多個線程同時遍歷它,要求每個線程使用
  • 淺談Python中的多線程
    「並發」其實在我們的生活中隨處可見,比如我們去銀行存錢,銀行如果只有一個窗口並且辦業務的人又比較多,那麼肯定就是排成一個長長的隊伍,這樣的體驗對我們來說肯定是非常差的。那麼該如何解決這個問題呢?那就是多開幾個窗口,把人流分散開,這樣就減短了我們隊伍的長度,減少整體排隊的時間。上面是我們顯示生活中遇到的問題,其實在計算機中我們也會遇到這樣的問題,那麼我們是怎麼解決的呢?
  • 多線程與多進程 | 多線程
    線程(Thread)是作業系統能夠進行運算調度的最小單位。他被包含在進程中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以並發多個線程,每條線程並行執行不同的任務。進程好比一列火車,多個進程就是多列火車。線程好比車廂,多個線程就是一條火車的多個車廂。線程需要在進程下運行,就好比單獨的車廂無法行駛一樣。創建線程Python3 線程中常用的兩個模塊為:thread 模塊已被廢棄。