深入剖析Android中Service和Thread區(qū)別
Service既不是進程也不是線程,它們之間的關系如下:
可能有的朋友會問了,既然是長耗時的操作,那么Thread也可以完成啊。沒錯,在程序里面很多耗時工作我們也可以通過Thread來完成,那么還需要Service干嘛呢。接下來就為大家解釋以下Service和Thread的區(qū)別。
首先要說明的是,進程是系統(tǒng)最小資源分配單位,而線程是則是最小的執(zhí)行單位,線程需要的資源通過它所在的進程獲取。
Service與Thread的區(qū)別:
Thread:Thread 是程序執(zhí)行的最小單元,可以用 Thread 來執(zhí)行一些異步的操作。
Service:Service 是android的一種機制,當它運行的時候如果是Local Service,那么對應的 Service 是運行在主進程的 main 線程上的。如果是Remote Service,那么對應的 Service 則是運行在獨立進程的 main 線程上。
Thread 的運行是獨立的,也就是說當一個 Activity 被 finish 之后,如果沒有主動停止 Thread 或者 Thread 里的 run 方法沒有執(zhí)行完畢的話,Thread 也會一直執(zhí)行。因此這里會出現(xiàn)一個問題:當 Activity 被 finish 之后,不再持有該 Thread 的引用,也就是不能再控制該Thread。另一方面,沒有辦法在不同的 Activity 中對同一 Thread 進行控制。
例如:如果 一個Thread 需要每隔一段時間連接服務器校驗數(shù)據(jù),該Thread需要在后臺一直運行。這時候如果創(chuàng)建該Thread的Activity被結(jié)束了而該Thread沒有停止,那么將沒有辦法再控制該Thread,除非kill掉該程序的進程。這時候如果創(chuàng)建并啟動一個 Service ,在 Service 里面創(chuàng)建、運行并控制該 Thread,這樣便解決了該問題(因為任何 Activity 都可以控制同一個Service,而系統(tǒng)也只會創(chuàng)建一個對應 Service 的實例)。
因此可以把 Service 想象成一種消息服務,可以在任何有 Context 的地方調(diào)用 Context.startService、Context.stopService、Context.bindService、Context.unbindService來控制它,也可以在 Service 里注冊 BroadcastReceiver,通過發(fā)送 broadcast 來達到控制的目的,這些都是 Thread 做不到的。
不少Android初學者都可能會有這樣的疑惑,Service和Thread到底有什么關系呢?什么時候應該用Service,什么時候又應該用Thread?答案可能會有點讓你吃驚,因為Service和Thread之間沒有任何關系!
之所以有不少人會把它們聯(lián)系起來,主要就是因為Service的后臺概念。Thread我們大家都知道,是用于開啟一個子線程,在這里去執(zhí)行一些耗時操作就不會阻塞主線程的運行。而Service我們最初理解的時候,總會覺得它是用來處理一些后臺任務的,一些比較耗時的操作也可以放在這里運行,這就會讓人產(chǎn)生混淆了。但是,如果我告訴你Service其實是運行在主線程里的,你還會覺得它和Thread有什么關系嗎?讓我們看一下這個殘酷的事實吧。
在MainActivity的onCreate()方法里加入一行打印當前線程id的語句:
Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());
然后在MyService的onCreate()方法里也加入一行打印當前線程id的語句:
Log.d("MyService", "MyService thread id is " + Thread.currentThread().getId());
現(xiàn)在重新運行一下程序,并點擊Start Service按鈕,會看到如下打印日志:
可以看到,它們的線程id完全是一樣的,由此證實了Service確實是運行在主線程里的,也就是說如果你在Service里編寫了非常耗時的代碼,程序必定會出現(xiàn)ANR的。
你可能會驚呼,這不是坑爹么!?那我要Service又有何用呢?其實大家不要把后臺和子線程聯(lián)系在一起就行了,這是兩個完全不同的概念。Android的后臺就是指,它的運行是完全不依賴UI的。即使Activity被銷毀,或者程序被關閉,只要進程還在,Service就可以繼續(xù)運行。比如說一些應用程序,始終需要與服務器之間始終保持著心跳連接,就可以使用Service來實現(xiàn)。你可能又會問,前面不是剛剛驗證過Service是運行在主線程里的么?在這里一直執(zhí)行著心跳連接,難道就不會阻塞主線程的運行嗎?當然會,但是我們可以在Service中再創(chuàng)建一個子線程,然后在這里去處理耗時邏輯就沒問題了。
額,既然在Service里也要創(chuàng)建一個子線程,那為什么不直接在Activity里創(chuàng)建呢?這是因為Activity很難對Thread進行控制,當Activity被銷毀之后,就沒有任何其它的辦法可以再重新獲取到之前創(chuàng)建的子線程的實例。而且在一個Activity中創(chuàng)建的子線程,另一個Activity無法對其進行操作。但是Service就不同了,所有的Activity都可以與Service進行關聯(lián),然后可以很方便地操作其中的方法,即使Activity被銷毀了,之后只要重新與Service建立關聯(lián),就又能夠獲取到原有的Service中Binder的實例。因此,使用Service來處理后臺任務,Activity就可以放心地finish,完全不需要擔心無法對后臺任務進行控制的情況。
以上就是小編為大家?guī)淼纳钊肫饰鯝ndroid中Service和Thread區(qū)別的全部內(nèi)容了,希望對大家有所幫助,多多支持腳本之家~
相關文章
詳解Android應用中屏幕尺寸的獲取及dp和px值的轉(zhuǎn)換
這篇文章主要介紹了Android應用中屏幕尺寸的獲取及dp和px值的轉(zhuǎn)換方法,這里主要介紹將dp轉(zhuǎn)化為px值的例子,需要的朋友可以參考下2016-03-03Android入門之ViewFlipper翻轉(zhuǎn)視圖的使用詳解
本篇給大家?guī)Я说氖荲iewFlipper,它是Android自帶的一個多頁面管理控件,且可以自動播放!本篇我們我們會使用兩個例子:一個自動播放首頁輪播頁一個手動可左右滑動道頁的輪播頁來說透這個組件的使用,感興趣的可以了解一下2022-11-11Android編程實現(xiàn)讀取手機聯(lián)系人、撥號、發(fā)送短信及長按菜單操作方法實例小結(jié)
這篇文章主要介紹了Android編程實現(xiàn)讀取手機聯(lián)系人、撥號、發(fā)送短信及長按菜單操作方法,以完整實例形式總結(jié)分析了Android編程實現(xiàn)讀取手機聯(lián)系人、撥號、發(fā)送短信及長按菜單等操作的相關技巧,需要的朋友可以參考下2015-10-10解決Android Studio 出現(xiàn)“Cannot resolve symbo
今天在調(diào)試的時候,Android Studio報了一個莫名其妙的錯誤Cannot resolve symbol'R'讓人不知所措,因為這東西根本不歸我管啊,怎么會出現(xiàn) Cannot resolve symbol 這種錯誤呢?下面給大家分享Android Studio 出現(xiàn)“Cannot resolve symbol”解決方案,需要的朋友可以參考下2023-03-03Android App開發(fā)中HTTP擴展包OkHttp的入門使用指南
OkHttp包為安卓開發(fā)中基于HTTP協(xié)議的網(wǎng)絡編程提供了很大便利,這里我們就來看一下Android App開發(fā)中HTTP擴展包OkHttp的入門使用指南:2016-07-07