Android Service和Thread的區別

原文地址:

http://www.cnblogs.com/carlo/p/4947342.html


Service既不是進程也不是線程,它們之間的關係如下:

 

      可能有的朋友會問了,既然是長耗時的操作,那麼Thread也可以完成啊。沒錯,在程序裏面很多耗時工作我們也可以通過Thread來完成,那麼還需要Service幹嘛呢。接下來就爲大家解釋以下Service和Thread的區別。

      首先要說明的是,進程是系統最小資源分配單位,而線程是則是最小的執行單位,線程需要的資源通過它所在的進程獲取。

      Service與Thread的區別:

      Thread:Thread 是程序執行的最小單元,可以用 Thread 來執行一些異步的操作。

      Service:Service 是android的一種機制,當它運行的時候如果是Local Service,那麼對應的 Service 是運行在主進程的 main 線程上的。如果是Remote Service,那麼對應的 Service 則是運行在獨立進程的 main 線程上。

      Thread 的運行是獨立的,也就是說當一個 Activity 被 finish 之後,如果沒有主動停止 Thread 或者 Thread 裏的 run 方法沒有執行完畢的話,Thread 也會一直執行。因此這裏會出現一個問題:當 Activity 被 finish 之後,不再持有該 Thread 的引用,也就是不能再控制該Thread。另一方面,沒有辦法在不同的 Activity 中對同一 Thread 進行控制。
      例如:如果 一個Thread 需要每隔一段時間連接服務器校驗數據,該Thread需要在後臺一直運行。這時候如果創建該Thread的Activity被結束了而該Thread沒有停止,那麼將沒有辦法再控制該Thread,除非kill掉該程序的進程。這時候如果創建並啓動一個 Service ,在 Service 裏面創建、運行並控制該 Thread,這樣便解決了該問題(因爲任何 Activity 都可以控制同一個Service,而系統也只會創建一個對應 Service 的實例)。
      因此可以把 Service 想象成一種消息服務,可以在任何有 Context 的地方調用 Context.startService、Context.stopService、Context.bindService、Context.unbindService來控制它,也可以在 Service 裏註冊 BroadcastReceiver,通過發送 broadcast 來達到控制的目的,這些都是 Thread 做不到的。

 

不少Android初學者都可能會有這樣的疑惑,Service和Thread到底有什麼關係呢?什麼時候應該用Service,什麼時候又應該用Thread?答案可能會有點讓你吃驚,因爲Service和Thread之間沒有任何關係!

之所以有不少人會把它們聯繫起來,主要就是因爲Service的後臺概念。Thread我們大家都知道,是用於開啓一個子線程,在這裏去執行一些耗時操作就不會阻塞主線程的運行。而Service我們最初理解的時候,總會覺得它是用來處理一些後臺任務的,一些比較耗時的操作也可以放在這裏運行,這就會讓人產生混淆了。但是,如果我告訴你Service其實是運行在主線程裏的,你還會覺得它和Thread有什麼關係嗎?讓我們看一下這個殘酷的事實吧。

在MainActivity的onCreate()方法里加入一行打印當前線程id的語句:

    Log.d("MyService", "MainActivity thread id is " + Thread.currentThread().getId());  

然後在MyService的onCreate()方法裏也加入一行打印當前線程id的語句:

現在重新運行一下程序,並點擊Start Service按鈕,會看到如下打印日誌:

                                 

可以看到,它們的線程id完全是一樣的,由此證實了Service確實是運行在主線程裏的,也就是說如果你在Service裏編寫了非常耗時的代碼,程序必定會出現ANR的

你可能會驚呼,這不是坑爹麼!?那我要Service又有何用呢?其實大家不要把後臺和子線程聯繫在一起就行了,這是兩個完全不同的概念。Android的後臺就是指,它的運行是完全不依賴UI的。即使Activity被銷燬,或者程序被關閉,只要進程還在,Service就可以繼續運行。比如說一些應用程序,始終需要與服務器之間始終保持着心跳連接,就可以使用Service來實現。你可能又會問,前面不是剛剛驗證過Service是運行在主線程裏的麼?在這裏一直執行着心跳連接,難道就不會阻塞主線程的運行嗎?當然會,但是我們可以在Service中再創建一個子線程,然後在這裏去處理耗時邏輯就沒問題了。

額,既然在Service裏也要創建一個子線程,那爲什麼不直接在Activity裏創建呢?這是因爲Activity很難對Thread進行控制,當Activity被銷燬之後,就沒有任何其它的辦法可以再重新獲取到之前創建的子線程的實例。而且在一個Activity中創建的子線程,另一個Activity無法對其進行操作。但是Service就不同了,所有的Activity都可以與Service進行關聯,然後可以很方便地操作其中的方法,即使Activity被銷燬了,之後只要重新與Service建立關聯,就又能夠獲取到原有的Service中Binder的實例。因此,使用Service來處理後臺任務,Activity就可以放心地finish,完全不需要擔心無法對後臺任務進行控制的情況。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章