後臺服務(九)

       後臺服務安全

1.在子線程中更新 UI是一種不安全的行爲,必須在主線程中進行,不然就會出現異常。可以使用Handler類方法進行替換異步


      解析異步消息處理機制
1.  Message
 Message是在線程之間傳遞的消息,它能夠在內部攜帶少許的信息,用於在不一樣線
 程之間交換數據。上一小節中咱們使用到了 Message 的 what 字段,除此以外還可使
 用 arg1和 arg2字段來攜帶一些整型數據,使用 obj字段攜帶一個 Object對象。
2.  Handler
 Handler 顧名思義也就是處理者的意思,它主要是用於發送和處理消息的。發送消
 息通常是使用 Handler 的 sendMessage()方法,而發出的消息通過一系列地展轉處理後,
 最終會傳遞到 Handler 的 handleMessage()方法中。
3.  MessageQueue
 MessageQueue 是消息隊列的意思,它主要用於存放全部經過 Handler 發送的消息。
 這部分消息會一直存在於消息隊列中, 等待被處理。 每一個線程中只會有一個 MessageQueue
 對象。
4.  Looper
 Looper 是每一個線程中的 MessageQueue 的管家,調用 Looper 的 loop()方法後,就會
 進入到一個無限循環當中,而後每當發現 MessageQueue 中存在一條消息,就會將它取
 出, 並傳遞到 Handler的 handleMessage()方法中。 每一個線程中也只會有一個 Looper 對象。oop

流程說明:首先須要在主線程當中建立一個 Handler 對象,並重寫
 handleMessage()方法。而後當子線程中須要進行 UI 操做時,就建立一個 Message 對象,並
 經過 Handler 將這條消息發送出去。以後這條消息會被添加到 MessageQueue 的隊列中等待
 被處理,而 Looper 則會一直嘗試從 MessageQueue 中取出待處理消息,最後分發回 Handler
 的 handleMessage()方法中。this

     使用 AsyncTask:
泛型參數:
 1.  Params
  在執行 AsyncTask時須要傳入的參數,可用於在後臺任務中使用。
 2.  Progress
  後臺任務執行時,若是須要在界面上顯示當前的進度,則使用這裏指定的泛型做爲進度單位。
 3.  Result
  當任務執行完畢後,若是須要對結果進行返回,則使用這裏指定的泛型做爲返回值類型。 線程

重寫方法:
 1.  onPreExecute()
  這個方法會在後臺任務開始執行以前調用,用於進行一些界面上的初始化操做,比
  如顯示一個進度條對話框等。
 2.  doInBackground(Params...)
  這個方法中的全部代碼都會在子線程中運行, 咱們應該在這裏去處理全部的耗時任
  務。任務一旦完成就能夠經過 return 語句來將任務的執行結果返回,若是 AsyncTask的
  第三個泛型參數指定的是 Void,就能夠不返回任務執行結果。注意,在這個方法中是不
  能夠進行 UI操做的,若是須要更新 UI元素,好比說反饋當前任務的執行進度,能夠調
  用 publishProgress(Progress...)方法來完成。
 3.  onProgressUpdate(Progress...)
  當在後臺任務中調用了 publishProgress(Progress...)方法後,這個方法就會很快被調
  用,方法中攜帶的參數就是在後臺任務中傳遞過來的。在這個方法中能夠對 UI 進行操
  做,利用參數中的數值就能夠對界面元素進行相應地更新。
 4.  onPostExecute(Result)
  當後臺任務執行完畢並經過 return語句進行返回時,這個方法就很快會被調用。返
  回的數據會做爲參數傳遞到此方法中,能夠利用返回的數據來進行一些 UI 操做,好比
  說提醒任務執行的結果,以及關閉掉進度條對話框等。對象

 

    服務的基本用法
1.定義一個服務:
 1.繼承 Service
 2.重寫了 onCreate()方法會在服務建立的時候調用、onStartCommand()方法會在每次服務啓動的時候調用
 和 onDestroy()方法會在服務銷燬的時候調用
 3.onBind(Intent i) 中具體的操做或者返回具體的操做類
 4.建立一個服務鏈接池。ServiceConnection onServiceConnected活動被綁定  onServiceDisconnected解除綁定
 5.經過這種方式啓動、關閉、綁定、解除綁定服務。
  Intent startIntent = new Intent(this, MyService.class);
                startService(startIntent); / stopService(stopIntent);  bindService(bindIntent, serviceConnection, BIND_AUTO_CREATE);     unbindService(serviceConnection);  繼承

      服務的生命週期
 服務也有本身的生命週期,前面咱們使用到的 onCreate()、onStartCommand()、onBind()和 onDestroy()等方法都是在服務的生命週期內可能回調的方法。
 一旦在項目的任何位置調用了 Context的 startService()方法,相應的服務就會啓動起來,並回調 onStartCommand()方法。若是這個服務以前尚未建立過,onCreate()方法會先於onStartCommand()方法執行。服務啓動了以後會一直保持運行狀態,直到 stopService()或stopSelf()方法被調用。注意雖然每調用一次 startService()方法,onStartCommand()就會執行一次, 但實際上每一個服務都只會存在一個實例。 因此無論你調用了多少次 startService()方法,只需調用一次 stopService()或 stopSelf()方法,服務就會中止下來了。
 另外,還能夠調用 Context 的 bindService()來獲取一個服務的持久鏈接,這時就會回調服務中的 onBind()方法。相似地,若是這個服務以前尚未建立過,onCreate()方法會先於onBind()方法執行。以後,調用方能夠獲取到 onBind()方法裏返回的 IBinder對象的實例,這樣就能自由地和服務進行通訊了。只要調用方和服務之間的鏈接沒有斷開,服務就會一直保持運行狀態。
 當調用了 startService()方法後,又去調用 stopService()方法,這時服務中的 onDestroy()方法就會執行,表示服務已經銷燬了。相似地,當調用了 bindService()方法後,又去調用unbindService()方法,onDestroy()方法也會執行,這兩種狀況都很好理解。可是須要注意,咱們是徹底有可能對一個服務既調用了 startService()方法,又調用了 bindService()方法的,這種狀況下該如何才能讓服務銷燬掉呢?根據 Android 系統的機制,一個服務只要被啓動或者被綁定了以後,就會一直處於運行狀態,必需要讓以上兩種條件同時不知足,服務才能被銷燬。因此,這種狀況下要同時調用 stopService()和 unbindService()方法,onDestroy()方法纔會執行。生命週期

 

      前臺服務
1.實現原理:在Service服務的onCreate方法中,經過通知的方式在前臺狀態中顯示隊列

 

      定時任務
1.Timer類:Timer有一個明顯的短板,它並不太適用於那些須要長期在後臺運行的定時任務。咱們都知道,爲了能讓電池更加耐用,每種手機都會有本身的休眠策略,Android 手機就會在長時間不操做的狀況下自動讓 CPU 進入到睡眠狀態,這就有可能致使 Timer中的定時任務沒法正運行。消息隊列

2.Alarm機制: AlarmManager的工做類型
 1. ELAPSED_REALTIME 表示讓定時任務的觸發時間從系統開機開始算起,但不會喚醒 CPU
 2.ELAPSED_REALTIME_WAKEUP 表示讓定時任務的觸發時間從系統開機開始算起,但會喚醒 CPU
 3.RTC 表示讓定時任務的觸發時間從 1970 年 1月 1日 0 點開始算起,但不會喚醒 CPU
 4.RTC_WAKEUP 表示讓定時任務的觸發時間從1970 年 1月 1 日 0 點開始算起,但會喚醒 CPU
 使用 SystemClock.elapsedRealtime()方法能夠獲取到系統開機至今所經歷時間的毫秒數
 使用 System.currentTimeMillis()方法能夠獲取到 1970年 1月 1 日 0點至今所經歷時間的毫秒數

相關文章
相關標籤/搜索